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

Почему Java имеет "NullPointerException", когда в Java нет указателей?

Почему я получаю исключение, называемое NullPointerException, если в Java нет такой концепции, как указатель?

4b9b3361

Ответ 1

Да, это одна из первых неприятных вещей, которые я узнал при изучении Java LOL. Это действительно должно быть вызвано NullReferenceException, NoObjectException или DereferenceException, как упоминалось paxdiablo. Ссылки даже не должны представляться внутренне как указатели, и вам не нужно заботиться. "Большинство виртуальных машин, включая Sun, используют дескрипторы, а не указатели. Рукоятка - это указатель на указатель, который знает, как они придумали это?" О, Microsoft Java VM фактически использует указатели, а не ручки, так что продолжайте рисовать.

Ответ 2

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

Тем не менее, Java по-прежнему необходимо различать объект и "нет объекта". Это просто название исключения, которое означает, что вы пытаетесь использовать ссылку на объект, у которой нет заднего объекта.

Вы можете так же легко называть его NoObjectException или DereferenceException, или одно из множества других имен, чтобы свести к минимуму вероятность того, что люди подумают, что Java имеет указатели общего назначения.

Но NullPointerException - это то, что выбрали создатели языка, вероятно, потому, что они использовались для кодирования на C и/или С++.

Ответ 3

Технически это правильно, его действительно следует называть NullReferenceException

Ответ 4

Поскольку внутренние переменные объекта являются указателями на эти объекты. Однако вы не получаете значение указателя, кроме как вызывая System.identityHashCode(объект) для большинства реализаций JVM, который возвращает указатель на объект.

EDIT: вы почти все в порядке, я был почти прав: identityHashCode намного сложнее, чем возврат указателя. Я просто посмотрел на источник JVM, и они встроили несколько генераторов hashcode. Однако, по крайней мере, в случае, когда hashCode (константа? я не знаю) является константой, они возвращают указатель объекта. Вот их источник для любопытных:

static inline intptr_t get_next_hash(Thread * Self, oop obj) {
  intptr_t value = 0 ;
  if (hashCode == 0) {
     // This form uses an unguarded global Park-Miller RNG,
     // so it possible for two threads to race and generate the same RNG.
     // On MP system we'll have lots of RW access to a global, so the
     // mechanism induces lots of coherency traffic.
     value = os::random() ;
  } else
  if (hashCode == 1) {
     // This variation has the property of being stable (idempotent)
     // between STW operations.  This can be useful in some of the 1-0
     // synchronization schemes.
     intptr_t addrBits = intptr_t(obj) >> 3 ;
     value = addrBits ^ (addrBits >> 5) ^ GVars.stwRandom ;
  } else
  if (hashCode == 2) {
     value = 1 ;            // for sensitivity testing
  } else
  if (hashCode == 3) {
     value = ++GVars.hcSequence ;
  } else
  if (hashCode == 4) {
     value = intptr_t(obj) ;
  } else {
     // Marsaglia xor-shift scheme with thread-specific state
     // This is probably the best overall implementation -- we'll
     // likely make this the default in future releases.
     unsigned t = Self->_hashStateX ;
     t ^= (t << 11) ;
     Self->_hashStateX = Self->_hashStateY ;
     Self->_hashStateY = Self->_hashStateZ ;
     Self->_hashStateZ = Self->_hashStateW ;
     unsigned v = Self->_hashStateW ;
     v = (v ^ (v >> 19)) ^ (t ^ (t >> 8)) ;
     Self->_hashStateW = v ;
     value = v ;
  }

  value &= markOopDesc::hash_mask;
  if (value == 0) value = 0xBAD ;
  assert (value != markOopDesc::no_hash, "invariant") ;
  TEVENT (hashCode: GENERATE) ;
  return value;
}

Ответ 5

Поскольку все переменные (по RHS присвоения), которые вы объявляете, являются ссылками на некоторые объекты в куче. Если ссылка не указывает на то, где тогда при доступе к этой переменной генерируется исключение nullpointer.

Ответ 6

Если у вас есть объект с let say список как атрибут, и вы явно не выделяете место для него, запущенная программа выдаст вам эту ошибку.

Посмотрите на отладчик (Eclipse или нет), чтобы увидеть, что ваши объекты хранятся, когда вы не инициализируете их правильно, а затем все будет довольно ясно.

Я думаю, что это было сделано так, что есть понятие между объектом, у которого есть место в памяти, и теми, которые этого не делают.