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

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

14
задан user2864740 11 October 2014 в 21:36
поделиться

6 ответов

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

7
ответ дан 1 December 2019 в 12:38
поделиться

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

РЕДАКТИРОВАТЬ: С вами почти все в порядке, я почти ошибался: identityHashCode намного сложнее, чем просто возврат указателя. Я только что взглянул на исходный код JVM, и они реализовали несколько генераторов хэш-кода. Однако, по крайней мере, в случае, когда 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's 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's 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;
}
2
ответ дан 1 December 2019 в 12:38
поделиться

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

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

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

-1
ответ дан 1 December 2019 в 12:38
поделиться

Технически это правильно, на самом деле это должно называться NullReferenceException

4
ответ дан 1 December 2019 в 12:38
поделиться

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

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

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

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

10
ответ дан 1 December 2019 в 12:38
поделиться

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

0
ответ дан 1 December 2019 в 12:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: