All objects in Java are references and you can use them like pointers.
abstract class Animal
{...
}
class Lion extends Animal
{...
}
class Tiger extends Animal
{
public Tiger() {...}
public void growl(){...}
}
Tiger first = null;
Tiger second = new Tiger();
Tiger third;
Dereferencing a null:
first.growl(); // ERROR, first is null.
third.growl(); // ERROR, third has not been initialized.
Aliasing Problem:
third = new Tiger();
first = third;
Losing Cells:
second = third; // Possible ERROR. The old value of second is lost.
You can make this safe by first assuring that there is no further need of the old value of second or assigning another pointer the value of second.
first = second;
second = third; //OK
Note that giving second a value in other ways (NULL, new...) is just as much a potential error and may result in losing the object that it points to.
The Java system will throw an exception (OutOfMemoryError
) when you call new and the allocator cannot allocate the requested cell. This is very rare and usually results from run-away recursion.
Note that, from a language point of view, abandoning objects to the garbage collector are not errors at all. It is just something that the programmer needs to be aware of. The same variable can point to different objects at different times and old values will be reclaimed when no pointer references them. But if the logic of the program requires maintaining at least one reference to the object, It will cause an error.
Novices often make the following error.
Tiger tony = new Tiger();
tony = third; // Error, the new object allocated above is reclaimed.
What you probably meant to say was:
Tiger tony = null;
tony = third; // OK.
Improper Casting:
Lion leo = new Lion();
Tiger tony = (Tiger)leo; // Always illegal and caught by compiler.
Animal whatever = new Lion(); // Legal.
Tiger tony = (Tiger)whatever; // Illegal, just as in previous example.
Lion leo = (Lion)whatever; // Legal, object whatever really is a Lion.
Pointers in C:
void main() {
int* x; // Allocate the pointers x and y
int* y; // (but not the pointees)
x = malloc(sizeof(int)); // Allocate an int pointee,
// and set x to point to it
*x = 42; // Dereference x to store 42 in its pointee
*y = 13; // CRASH -- y does not have a pointee yet
y = x; // Pointer assignment sets y to point to x's pointee
*y = 13; // Dereference y to store 13 in its (shared) pointee
}
Pointers in Java:
class IntObj {
public int value;
}
public class Binky() {
public static void main(String[] args) {
IntObj x; // Allocate the pointers x and y
IntObj y; // (but not the IntObj pointees)
x = new IntObj(); // Allocate an IntObj pointee
// and set x to point to it
x.value = 42; // Dereference x to store 42 in its pointee
y.value = 13; // CRASH -- y does not have a pointee yet
y = x; // Pointer assignment sets y to point to x's pointee
y.value = 13; // Deference y to store 13 in its (shared) pointee
}
}
UPDATE: as suggested in the comments one must note that C has pointer arithmetic. However, we do not have that in Java.