Получить операцию, предпринятую в случае NPE
Рассмотрим приведенный ниже код:
String s = null;
s.toLowerCase();
Он выбрасывает NPE:
Исключение в потоке "main" java.lang.NullPointerException
на pracJava1.Prac.main(Prac.java:7)
Возникает вопрос: почему JVM также не может передать сообщение помощника:
Исключение в потоке "main" java.lang.NullPointerException. Попытка toLowerCase() on null
Это полезно в таких случаях, как obj.setName(s.toLowerCase())
, где номера строк недостаточно, чтобы угадать, было ли значение obj
равно null или s
.
О возможности его использования, посмотрим на генерируемый байт:
stack=1, locals=2, args_size=1
0: aconst_null
1: astore_1
2: aload_1
3: invokevirtual #2 // Method java/lang/String.toLowerCase:()Ljava/lang/String;
Значит, возможно, он знает, имя метода, в котором она пыталась выполнить операцию. Эксперты JVM, каково ваше мнение?
Ответы
Ответ 1
Почему JVM не может помещать вспомогательное сообщение
Прежде всего, JVM может сделать это. Например, SAP JVM действительно предоставляет расширенные сообщения для NullPointerExceptions, ClassCastExceptions и т.д.
Были запросы, чтобы сделать то же самое для JVM HotSpot, но они были закрыты как Will-Not-Fix по причинам, упомянутым в @StephenC ответ.
Тем не менее, можно обогащать сообщения NullPointerException с помощью агента JVM TI.
Пример распространения сообщений NPE
Ответ 2
Одна из возможных причин не делать этого - это может сломать старый Java-код. Во всех реализациях классической Java с самого начала атрибут сообщения NPE, созданный самой JVM, был null
.
Любые изменения, которые нарушают старый код приложения, наносят ущерб бизнес-модели Sun/Oracle для Java. Все данные свидетельствуют о том, что Sun/Oracle пытаются избежать этого, если альтернатива хуже.
(Иногда случаются ошибки/недоразумения, и (возможно) ненужное "нарушение" изменений в Java проскальзывает. Мы видим, что в результате "вопиющих возмущений" с определенных сторон, и я полагаю, что Oracle также получает обратную связь через свои контакты с клиентами.)
Android "Java" делает это по-другому. (И это показывает, что сообщения об ошибках NPE были бы технически осуществимы на Java). Но Google не нужно было беспокоиться о совместимости для старых классических приложений Java. Они отказались от этой проблемы, когда заменили образцы стандартных библиотек Java SE на альтернативы Android.
Вы прокомментировали:
Но Oracle много раз нарушал изменения совместимости, где спецификация api не была нарушена (но внутренняя часть была изменена). Если кто-то разбирал сообщение об ошибке NPE, я не думаю, что это достаточно хорошая причина:)
Это хорошие точки обсуждения (возможно).
Однако это решение не открыто для обсуждения. Это было решение бизнес, которое Sun сделала много лет назад, и Oracle выбрала поддержку. Мы не знаем, что такое настоящие рассуждения. и то, что вы или я думаю о гипотетическом рассуждении, не имеет никакого отношения.
Для записи это было предложено как RFE (JDK-4834738) еще в 2003 году. Вопрос был в конечном счете закрыт в 2014 году, поскольку WNF (не будет исправлено). Никакой причины не было (публично).