Как я могу поймать NoSuchMethodException? - PullRequest
4 голосов
/ 26 июля 2011

Есть некоторые несовместимые изменения в коде, от которых я зависит. Поэтому я хочу поймать исключение NoSuchMethodException для регистрации дополнительной информации о проблеме

Когда я использую это:

try{
     do.something();      
}catch(NoSuchMethodException e){
     System.out.println("!");
}

Я получаю эту ошибку «Недоступный блок перехвата для NoSuchMethodException. Это исключение никогда не выдается из тела оператора try»

Я также пытался перехватить java.lang.RuntimeException и проверить, не является ли он NoSuchMethod, но он не работает.

Отражение приведет к задержкам производительности и не будет его использовать ....

Есть идеи?

Ответы [ 7 ]

7 голосов
/ 26 июля 2011

Вы перепутали с NoSuchMethodException, которое генерируется только при вызове метода, который не существует с использованием отражения, и NoSuchMethodError, который может быть сгенерирован при непосредственном вызове метода, когда этот метод существует во время компиляции и не существует во время выполнения.Обычно это происходит при использовании разных версий некоторой внешней библиотеки во время компиляции и выполнения.

Итог: catch NoSuchMethodError

5 голосов
/ 26 июля 2011

Catch NoSuchMethodError вместо. Однако это выглядит как уродливый обходной путь, и я бы порекомендовал просто решить проблему несовместимости.

1 голос
/ 26 июля 2011

Во-первых, я категорически не согласен со всеми, кто говорит вам ловить ошибки.Не делай этого.Ошибки должны быть оставлены в покое, чтобы всплыть любой обработчик исключений в вашем приложении.Если ваше приложение делает это, то все, что вам нужно сделать, чтобы получить свидетельство несовместимости, - это grep вашего файла журнала.

Кроме того, не оценивайте код, используя отражение, пока вы не профилируете его и не выясните точнокак долго.Обычно догадки о том, где замедления в конечном итоге являются неправильными.Вы никогда не должны ничего оптимизировать, пока не проведете измерения и не продемонстрируете, что это узкое место.

Копайте код do.something, декомпилируйте его, если у вас нет исходного кода, и посмотрите, что на самом деле выбрасываетЭто.Возможно, если возникнет исключение, оно может быть заключено в другое исключение.Убедитесь, что все, что выкинуло методом, не съедено (в том числе и вашим собственным логом).

1 голос
/ 26 июля 2011

РЕДАКТИРОВАТЬ : Это общее решение о том, как объявлять проверенные исключения. Как уже отмечали другие, вы должны поймать NoSuchMethodError или даже IncompatibleClassChangeError , потому что это то, что будет выброшено во время выполнения.


Поскольку вы хотите ссылаться на другую версию этой библиотеки, отличную от компиляции (не рекомендуется сама по себе, но я не из тех, кто судит), вам необходимо сообщить компилятору, что все в порядке.

Один из способов сделать это в этом случае - создать статический помощник, который объявляет исключение:

class Util {
    public static void unsafeApiCall() throws NoSuchMethodException {
        // if (false) prevents a compilation error
        if (false) throw new NoSuchMethodException();
    };
}

использовать как

try {
    Util.unsafeApiCall();
    do.something();      
} catch(NoSuchMethodException e2) {
    System.out.println("!");
}

Это также выделяется визуально, и это хорошо.


EDIT2 : Такая вещь может быть необязательной, если вы бросаете проверенные исключения, не объявляя их, как описано здесь .

1 голос
/ 26 июля 2011

Недоступный блок перехвата для исключения NoSuchMethodException. Это исключение никогда не выбрасывается из тела оператора try

Как говорится в IDE / Compiler. В теле try никогда не создается исключение NoSuchMethodException. Это означает, что ни один из методов, которые вы вызываете, не объявлен как:

public void doSomething() throws NoSuchMethodException

и в теле попытки никогда не добавляется буквально NoSuchMethodException:

throw new NoSuchMethodException();
1 голос
/ 26 июля 2011

Я бы порекомендовал вам ответить @matt b.Используйте это NoSuchMethodError.

Но, если вы вообще хотите перехватить NoSuchMethodException, вам придется явно выбросить его, используя

throw new NoSuchMethodException();
1 голос
/ 26 июля 2011

NoSuchMethod должен означать, что вы пытаетесь получить доступ к методу, который не существует, вероятно, во время выполнения.Лучше всего, если вы исправите это, чем пытаетесь поймать исключение.

Лучше разместить метод там, где он должен быть, чтобы у вас не было логических ошибок, таких как неправильный вывод и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...