Фон
Этот вопрос связан с Почему String.valueOf(null) выдает исключение NullPointerException?
Рассмотрим следующий фрагмент:
public class StringValueOfNull {
public static void main(String[] args) {
String.valueOf(null);
// programmer intention is to invoke valueOf(Object), but instead
// code invokes valueOf(char[]) and throws NullPointerException
}
}
Как объясняется в ответе на связанный вопрос, перегрузка Java-метода разрешает вышеупомянутую инволюцию на String.valueOf(char[])
, что по праву приводит к NullPointerException
во время выполнения.
Скомпилированный в Eclipse и javac 1.6.0_17
, это трассировка стека:
Exception in thread "main" java.lang.NullPointerException
at java.lang.String.<init>(Unknown Source)
at java.lang.String.valueOf(Unknown Source)
at StringValueOfNull.main(StringValueOfNull.java:3)
Обратите внимание, что в приведенной выше трассе стека отсутствует информация KEY: у нее нет полной подписи метода valueOf
! Он просто говорит String.valueOf(Unknown Source)
!
В большинстве ситуаций, с которыми я столкнулся, трассировки стека исключений всегда имеют полную подпись методов, которые на самом деле находятся в трассировке стека, что, конечно же, очень полезно для немедленной идентификации проблемы и основной причины, по которой трассировка стека ( который, разумеется, довольно дорог для постройки) предоставляется в первую очередь.
И все же в этом случае трассировка стека вообще не помогает. Он с треском провалился, помогая программисту идентифицировать проблему.
Как есть, я вижу три способа, которыми программист может идентифицировать проблему с приведенным выше фрагментом:
- Программист сам понимает, что метод перегружен, и по правилу разрешения в этом случае вызывается "неправильная" перегрузка
- Программист использует хорошую среду IDE, которая позволяет ему/ей быстро видеть, какой метод выбран
- В Eclipse, например, при наведении указателя мыши на указанное выше выражение быстро сообщает программисту, что
String valueOf(char[] data)
действительно выбран один
- В Eclipse, например, при наведении указателя мыши на указанное выше выражение быстро сообщает программисту, что
- Программист проверяет байт-код (тьфу!)
Последняя опция, вероятно, является наименее доступной, но, конечно же, является окончательным ответом (программист может неправильно понимать правило перегрузки, IDE может быть ошибкой, но байткоды всегда (?) говорят правду о том, что делается).
Вопросы
- Почему трассировка стека настолько неинформативна в этом случае в отношении сигнатур методов, которые фактически находятся в трассировке стека?
- Это из-за компилятора? Время выполнения? Что-то еще?
- В каких других (редких?) сценариях трассировка стека может не захватывать важную информацию, подобную этим?