Ответ 1
Код мертв в любой версии Java. Для конструктора невозможно вернуть null
, и даже если из конструктора будет сгенерировано исключение, следующая строка вызываться не будет.
Просматривая старый код, я наткнулся на этот камень:
MyObject o = new MyObject("parameter");
if (o == null) o = new MyObject("fallback parameter");
Вторая строка отмечена в Eclipse как мертвый код, и я понимаю, почему. Никакое исключение явно не выбрано, и конструктор MyObject
не может выбрасывать какое-либо исключение (например, NullPointerException
s).
Мой вопрос - почему существует нулевая проверка? Возможно ли это ранее в старой версии Java для того, чтобы конструктор возвращал значение null? Или это просто бесполезный и мертвый код?
Код мертв в любой версии Java. Для конструктора невозможно вернуть null
, и даже если из конструктора будет сгенерировано исключение, следующая строка вызываться не будет.
Нет, это никогда не было возможным. Возможно, в предыдущей версии кода использовался некоторый метод factory, который мог бы возвращать значение null:
MyObject o = createMyObject("parameter");
if (o == null) o = createMyObject("fallback parameter");
Значение выражения создания экземпляра класса является ссылкой на вновь созданный объект указанного класса. Каждый раз, когда выражение оценивается, создается новый объект.
Нет, он никогда не сможет вернуть null.
Я предполагаю, что он был написан программистом C, который используется для тестирования возвращаемого значения malloc()
для NULL
, malloc()
может возвращать NULL
, если в вашей системе не хватает памяти.
Код не имеет смысла в Java, так как Java будет вызывать OutOfMemoryError`, если в нем заканчивается память.
Ответ прост: человек, который написал код, был параноидным программистом на С++. В С++ вы можете перегрузить оператор new и использовать его как простой распределитель памяти (aka malloc).
Это был просто бесполезный мертвый код. Как только CTOR выполнит успешно, вы ссылаетесь на объект.
Когда вы создаете новый Object(), вы создаете адрес в памяти, и этот адрес не "null", но ваш объект может быть пустым.
Вы должны проверить 'null' для объекта, переданного параметрами.
Это просто мертвый код.
new MyObject("parameter")
не вернет null
в любой версии java.
Как я обнаружил сегодня, несмотря на то, что сказано во всех других ответах, Foo x = new Foo(...)
действительно может вернуть null, если указанный код работает внутри теста, который использует PowerMock (или какая-то другая насмешливая структура с похожими эффектами):
PowerMockito.whenNew(Foo.class).withAnyArguments().thenReturn(mockFoo);
В этом случае код конструктора (ов) Foo вообще исключается для new Foo(...)
. Но если вы напишете тест, в котором вы не укажете макет в приведенном выше порядке, вы можете вместо этого использовать null
.
Но даже если вы используете такую фреймворк, вам не нужен дополнительный код в ваших классах, просто чтобы грациозно обработать случай, который вы забыли правильно издеваться над объектами в тесте! Это не реальный сценарий, когда ваш код предназначен для запуска. Код, который только когда-либо активен, когда тестирование должно быть устранено в любом случае, и в этом случае оно будет только когда-либо действовать для сломанного теста.
Таким образом, даже если вы используете PowerMock, эта вторая строка должна по праву считаться "мертвым кодом" и удалена.
Если вторая строка мертва, и первая строка является единственным способом создания объекта, то, я думаю, исключение NullPointerException никогда не произойдет!!!
(Если вы не запускали что-то вроде 0.aMethod()
. Но я слышал, что в java даже целые объекты являются объектами, поэтому, возможно, на языке, где вы не можете указывать указатели - у вас не может быть указателей на указатель.) (Много сарказм в приведенном выше!)
Это уже случилось со мной, когда я переопределяю метод toString
...
public String toString(){
return description;
}
пока не уверен.