Подтвердить что ты не робот

Unboxing Null-Object для длительных результатов в NullPointerException, отлично?

Этот фрагмент выдает NullPointerException из-за того, что его unboxed на примитивный тип и Long.longValue() вызывается, правильно?

Это даже легко увидеть, если у вас есть такой сниппет:

long value = (Long) null;

Но NullPointerException еще сложнее попасть в более сложную ситуацию следующим образом:

long propertyValue = (Long) obj.getProperty(propertyModel.getName());

Итак, нет ли возможности для Java-Compiler сделать из этого более комфортным Исключение? Я бы предпочел IllegalArgumentException с сообщением типа "Вы пытаетесь применить null-Object в примитивный тип, это невозможно!"

Разве это не было бы более уместным? Как вы думаете? Возможно ли это во время выполнения? Можем ли мы определить этот актерский состав? Я еще не посмотрел на java-байт-код. Возможно, он может быть использован в решении.

На этот вопрос можно ответить. Я хотел бы знать, возможно ли достичь такого поведения!

4b9b3361

Ответ 1

В соответствии с спецификацией языка Java, unboxing происходит через вызовы Number.longValue(), Number.intValue() и т.д. Нет специальной магии байтового кода Это точно так же, как если бы вы вызывали эти методы вручную. Таким образом, NullPointerException является естественным результатом распаковки a null (и, по сути, JLS).

Для исключения другого исключения потребуется проверка для null дважды во время каждого преобразования unboxing (один раз, чтобы определить, нужно ли бросать специальное исключение и некогда неявно, когда метод фактически вызывается). Я полагаю, что разработчики языка не считали это достаточно полезным, чтобы гарантировать это.

Ответ 2

Это не то, что означает IllegalArgumentException. Компилятор не гарантирует, что значение будет null до времени выполнения. Все, что он знает, это тип, который в вашем примере, вероятно, будет String.

Конечно, во время выполнения, когда генерируется исключение, компилятор знает, что проблема - это значение null. Вы сами это видите, если используете отладчик. Итак, с технологической точки зрения - и вот короткий ответ на ваш вопрос - да, было бы возможно создать компилятор, который будет включать это в описание ошибки. Но если вам нужно специальное сообщение для значений null, что дальше? Специальные сообщения для целых чисел, которые находятся за пределами допустимой границы более чем на 10? По общему признанию, это глупый пример, но я надеюсь, что это иллюстративно.

Ответ 3

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

Хорошо добавить достаточное "состояние" операции в исключение (в этом случае имя опции и значение - возможно, даже строковое представление карты опций, если не найдено).

Что-то вроде:

private long safeGetLong(Map<String, Option> options, String name) {
  if (name == null || options == null)
    throw new IllegalArgumentExcption("You need to give options and name. (name="+name+", opts=" + options));
  Object val = options.get(name);
  if (val == null)
    throw new ConfigurationException("The option name="+name+" is unknown");
  if (val instanceof Long)
    return val.longValue();

  String strVal = null;
  try
  {
    strVal = val.toString();
    return Long.parseValue(strVal);
  } catch (Exception ex) {
    throw new ConfigurationException("Cannot parse " + name + "=" + strVal + " into a Long.");
  }
}

Конечно, наличие объекта конфигурации, который позволяет типизировать доступ, еще лучше.

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

Ответ 4

Так как Java 8 SE также есть Optional.ofNullable

long value = Optional.ofNullable(obj.getProperty(propertyModel.getName())).orElse(0L)));