Java: Primitives vs Objects and References

Examples of primitive values
  • The integer 5
  • The floating point value 3.2
  • true
  • The character 'c'
Examples of objects
  • A person
  • A date
  • The string "Hello"
  • A list

You could view primitive values as actual data, and objects as containers of data. If primitive values where atoms, objects would be molecules.

Objects and primitive values have types. There are 8 primitive types in Java:

All other types (String, List, YourCustomClass, …) are reference types.

Important: Note that it's called reference types and not object types. In Java you never work with objects directly; you always work with references (“pointers”) to objects.

Example

By running this snippet of code…

int i = 17;
Person p = new Person();
p.age = 34;

…you would end up with memory looking something like:

i 17 p age 34

i, which is of primitive type int holds some data, and p, which is of reference type, holds a reference to some data.

How data is passed around

The topic discussed below is a source of a lot of confusion, yet very important to fully understand. Read carefully!

First, two examples of what is meant by data being "passed around":

someMethod(x); // content of x is passed to someMethod
y = x;         // content of x is passed (copied) to y

There are three separate things involved here:

When you create an object all you get is a reference to it. There's no way to "pull the thread" and get hold of the actual object it points at. Since you can't get hold of objects, you can't pass them around! That's right, you can never pass an object as argument to a method! When people (sloppily) say that an object is passed to a method, what they mean is that a reference pointing at an object is passed to the method.

Key fact 1:
Objects aren't passed around at all.

Primitive values and references on the other hand are passed around, and both are treated the same way. If you call method(x) it behaves precisely the same regardless if x is of primitive type or of reference type: The content of x (whether it's an integer, a boolean value or a reference to an object) is copied and passed as argument to the method.

In programming lingo, "passing a copy of the content of a variable" is called pass by value.

Key fact 2:
Primitives and references are passed by value.

So, if someone says to you "Objects are passed by reference" (which is indeed a common misconception), you should reply with, "No, objects aren't passed around at all. References are passed around, and they are passed around by value."

If they continue to argue with you, just say you learned it first hand from someone with a PhD in theoretical computer science that have spent three years at Oracle developing the Java compiler.

That being said, there's an important final point to be made. When a reference is passed to a method, only the reference is copied, not the object. In other words, you'll have two references pointing at the same object. If you for instance have the following method…

void someMethod(Person x) {
    x.name = "Andreas";
}

…and do…

Person p = new Person();
p.name = "John";
someMethod(p);
System.out.println(p.name);

…it will print Andreas. If this surprises you, recall that p contains a reference to the Person object, and that when you call someMethod(p) this reference is passed on, and when the method uses it, it still points at the original object.

Key fact 3:
If a method modifies an object, the modification is visible outside that method.

Comparison to C/C++

Objects can only be created using the new keyword. Primitive types such as int can not be created using the new keyword.

Semantically Java references are similar to C/C++ pointers.

Syntactically Java references are similar to C++ references.

Java references C/C++ pointers C++ references
Points at objects Yes Yes Yes
Initialized with new Yes Yes No
Can be null Yes Yes No
Can be updated to point at a different object Yes Yes No
Pass by value Yes Yes No
Is called "reference" Yes No Yes
Is implicitly dereferenced Yes No Yes

Comments (2)

User avatar

Thank you! Very helpful! Could you give a code example of a method which accepts not a Person reference, but a primitive data type someMethod(int a). Is the value going to change outside the method?

by Ktisin |  Reply
User avatar

The argument would not be changed outside the method. The method would work with a copy of the argument. (See paragraph below Key Fact 1.) Note that this is true also for references; references are copied too.

by Andreas Lundblad |  Reply

Add comment