What are References in Java?

So Java has references. But what about pointers and pass-by-reference? References in Java are different to PHP, C# and other languages. And this can cause some confusion. 

About References in Java

In Java a reference is the value of a reference type expression.
The expression itself could, for example, be a variable or a method. Here’s an example of a reference type variable and how it is used:

BigInteger answer = BigInteger.valueOf(42);

Here “answer” is the name of the variable. The method valueOf returns a reference. The method println takes a parameter of reference type. Another reference is println. System is just a class name and it is used similarly to a reference in that it gives access to all static members of that class.

Other examples of reference expressions are:

"string literal" // string in string pool
new Foo() // newly created object
SomeEnum.ENUM_NAME // enum constant
null // null literal 

Reference Types

A reference type is anything that isn’t primitive (long, int, double, boolean etc.). So if the type of an expression is that of a class or interface, then it is a reference type. A variable of Type Integer is of reference type. A variable of type int is of primitive type.

Java is Pass-by-Value!

But what does it mean when a method takes a reference as a parameter. Java is “pass-by-value”. And the value of the variable “answer” is a reference. So a copy of the reference value is passed to the method. This works exactly the same as with primitive values, where a copy of the value is passed as well.
This is why in Java a method can only alter local variables, and fields of reachable objects. Usually you’d only alter fields of “this”, which is a reference and can be accessed like a local variable. You can actually alter the value of all (nonfinal) parameters, but that won’t alter the variable that was used to pass a value.
I explain pass-by-reference later.

Null Reference

In Java you can use null in your code. Technically it’s not a keyword. It’s a “literal”. Just like 42 is an integer literal and "foo" is a String literal. It is special because null can be assigned to all variables of reference type.
From the JLS: The null type has one value, the null reference, represented by the null literal null

What you can do with References

You can do a lot and I list all operations here:
What Operations can be performed on a Reference in Java?

Method References and Lambdas

Since Java 8 you can use method references and lambdas (closures). The compiler creates an object (all objects are reference type) and so the reference isn’t different from other references. Such references can be used as alternatives to pass-by-reference (see below).

What References in Java are not

Not visible

You can not see the reference. Some beginners think that toString() or hashCode() would show you the reference in HEX, but that is a misconception! Even though Java is pass-by-value, you can’t actually get that value.

Not persistent

You can not store a java reference into a database or file. Since it isn’t visible you wouldn’t even get the value. And during the lifetime of an object the value might actually change. That is up to the JVM.

Not an Identifier, not a Pointer, and not a Memory Address

Only the JVM knows how to interpret the reference. And when you shut down the JVM all those references are gone. That’s why you need identifier-fields if you use tools like JAX-B or Hibernate. The tool can then use those unique identifiers. The JVM probably uses 64 integers internally, but you don’t know and it doesn’t matter anyway.

Not Variables

Don’t confuse the variable with the reference. A reference type variable has a value and that value is a reference. int foo has an integer as a value. Integer foo holds a reference to an Integer and that Integer holds an integer value.

Java has no Pass-by-Reference!

Java simply doesn’t have that feature. And the term “reference” in “pass-by-reference” means something very different from what references are in Java! Other languages (C#, PHP, Pascal etc) have pass-by-reference and that means that not the value of a variable is passed. Instead a reference to the variable itself (not its value) is passed. Then the method (or function as they are called in other languages) can alter the value of the variable that was used when it was called. This kind of reference is just the offset to the variable, which is on another stack frame.

In other words: Java has references. Other languages have references and pointers. Java references are more like pointers than references. But they are still not the same. So you have three different things:

  • Java reference: Allows access to some object or no object (null).
  • Pointer: Memory address, allows access to data on heap.
  • References: Allow access to variables of method invoker when passed by reference.

In the following post I explain this in more detail and list some alternatives:
Pass-By-Reference in Java

4 thoughts on “What are References in Java?”

Leave a Reply

Your email address will not be published. Required fields are marked *