Предложение Java 'throws' не требуется при создании нового NPE? и почему добавление throws Exception дает ошибки компиляции?

Меня заинтересовало предложение 'throws', и я написал следующий фрагмент кода (я использую Eclipse с Java7). Первоначально я начал только с блоков 1 и 5 (ожидая ошибки компиляции, которой не произошло...), а затем это привело меня к написанию других блоков.

// 1
public void throwNPE() {
    throw new NullPointerException();
}

// 2
public void throwNPEWithGenericClause() throws Exception {
    throw new NullPointerException();
}

// 3
public void throwNPEWithNPEClause() throws NullPointerException {
    throw new NullPointerException();
}

// 4
public void throwNPEWithIAEClause() throws IllegalArgumentException {
    throw new NullPointerException();
}

// 5
public void callThrowNPE() {
    throwNPE();
}

// 6
public void callThrowNPEWithGenericClause() {
    throwNPEWithGenericClause(); // COMPILATION ERROR
}

// 7
public void callThrowNPEWithNPEClause() {
    throwNPEWithNPEClause();
}

// 8
public void callThrowNPEWithIAEClause() {
    throwNPEWithIAEClause();
}

Честно говоря, я ожидал:

(a) ошибка компиляции в 1. (необработанное исключение? Разве мой метод не должен уведомлять любой «последующий вызывающий объект» о том, что это вызовет какое-то исключение?)

(b) какая-то проблема в 4. (возможно, ошибка компиляции? Я выбрасываю NPE, в то время как в предложении написано IAE)

(c) ошибки компиляции в 5. 6. 7. и 8. (необработанные исключения? Я опускаю предложение 'throws')

(d) возможно, кто-нибудь мог бы также сказать мне, почему 6. является единственным, где я получил ошибку компиляции...


person PLB    schedule 12.03.2015    source источник
comment
Узнайте о необработанных исключениях.   -  person SLaks    schedule 12.03.2015
comment
Вам не нужно перехватывать и обрабатывать исключения RuntimeException, такие как NullPointerException или IllegalArgumentException.   -  person Pshemo    schedule 12.03.2015
comment
о, это меняет правила игры. спасибо посмотрю!   -  person PLB    schedule 12.03.2015


Ответы (3)


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

1) NullPointerException extends RuntimeException поэтому компилятор не выдает никакой ошибки.

2) Несмотря на то, что ваш метод генерирует NullPointerException, поскольку вы пометили метод throws Exception, компилятор предупреждает вас, чтобы вы перехватили его в своих вызывающих программах.

3) То же, что и 1-й ответ

4) То же, что и 1-й ответ IllegalArgumentException extends RuntimeException

5) throwNPE вообще ничего не кидает.

6) Несмотря на то, что вы выбрасываете NullPointerException (RuntimeException) в throwNPEWithGenericClause, поскольку вы помечаете метод как проверенное исключение, компилятор не разрешает.

7, 8) То же, что и 1-й ответ. Оба исключения времени выполнения, не нужно проверять.

person Onur Aktaş    schedule 12.03.2015
comment
спасибо за пошаговое объяснение! - person PLB; 13.03.2015

Исключения в Java можно разделить на три разных базовых типа:

Ошибка (генерируется JVM, если происходит фатальная ошибка)

Exception (все проверенные исключения наследуются от этого )

RuntimeException (от него наследуются все неотмеченные исключения)

Все они являются Throwables.

person Christian Kuetbach    schedule 12.03.2015
comment
@christian-kuetback прав. Кроме того, throws не означает, что Exception должен быть внутри try catch, тип исключения означает! - person Danilo Gomes; 13.03.2015

Экземпляры RuntimeException или Unchecked Exception, такие как NPE, не требуют броска/ловли. Их можно поймать, но, как правило, вы этого не хотите, потому что это указывает на ненормальный ход программы и должен завершить программу. В общем, если нет возможности продолжить, он завершится как RuntimeException. Если вы хотите предотвратить какое-либо действие с нулевым значением, вам следует проверить, является ли оно нулевым, а не ожидать NPE.

person tinker    schedule 12.03.2015