Java: Primitives vs Objects and References
- The integer 5
- The floating point value 3.2
- true
- The character 'c'
- 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:
- Integers
byte
(−128–127)short
(±32 thousand)int
(±2 billion)long
(±9 quintillion)
- Reals
float
(~6 digits precision)double
(~15 digits precision)
char
(unicode characters:a
5
,ξ
,♪
, …)boolean
(true/false)
All other types (String
, List
, YourCustomClass
, …) are reference types.
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
, 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:
- Primitive values
- References to objects
- Objects
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.
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.
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.
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 |
Thank you! Very helpful! Could you give a code example of a method which accepts not a
Person
reference, but a primitive data typesomeMethod(int a)
. Is the value going to change outside the method?by Ktisin |
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 |