Strictly speaking, in Java, a pointer is a reference that is guaranteed not
to be null. However, when people use the term
pointer, they usually mean C++ style direct hardware address pointers.
You may have heard some FUDster claiming that “Java sucks roadkill”
because it has no pointers. He jeers, “How can you write serious code
without pointers? In Java are you actually limited to FØRTRAN style
problems: no linked lists, no queues etc?” Java does not have raw pointers
like C or C++. It has something almost as powerful, but many times safer called references
(Java refers to them as pointers in one place, the NullPointerException).
They are like pointers, except that the dangerous features are removed, namely:
- pointer arithmetic.
- random initialisation values from failure to initialise.
- dangling pointers to deleted Objects. Java has garbage
collection — automatic detection and deletion of Objects
no longer is use.
- mismatched types and unions.
- You can’t construct references out of thin air, only with new.
- Unlike pointers, references cannot point into the middle of an Object.
- References are null or always point to something
valid of the type they claim to.
- Pointers always point directly to data. References are usually implemented as
handles, not pointers. A handle is a pointer to a pointer. This allows Objects
to be moved around to compact fragmented RAM without having to find and adjust
all the pointers to those Objects.
- In C++ you explicitly reference and dereference the layers of pointer
indirection to get at the data or to more direct pointers using a subtle
interplay of &, *,
-> and .
operators. This gets quite convoluted. In Java you rarely think about
defreferencing. Java automatically deferences as needed helped along with the
uniform referenencing/defreferencing . operator
where there is more that one level of indirection. For privitives and direct
references to Objects, there is no need for an
operator of any kind.
The safety comes with a cost.
- Every downcast has to be checked at run time to ensure the Object
truly is of the type your cast claims it to be.
- Nearly every time you put an Object into an array,
the runtime must check the type to be sure it is compatible with the allocated
type of the array, (which is distinct from the declared
type of the array reference.)
- Implementations of linked structures typically require extra tiny glue Objects
that point to the Objects linked. With raw pointers,
typically you manage to embed these pointers directly into your Objects.
Here’s my take on what happened. Originally Java’s references were called pointers.
However, the term pointer had a bad rap from what chaos happens when you
allow pointer arithmetic, optional initialisation and manual object recycling.
So they decided to rename them references. But old habits die hard, and
people, even those at Sun, sometimes continued to call them pointers. The
further wanted a new term that allowed for the many ways you can implement Java
pointers e.g. via machine virtual RAM pointers, segmented pointers, 64-bit
addressing pointers or handles. The word pointer leaked through in various
places including NullPointerException.