What is meant by ‘value semantics’, and what is meant by ‘implicit pointer semantics’?
4 Answers
Java is using implicit pointer semantics for Object types and value semantics for primitives.
Value semantics means that you deal directly with values and that you pass copies around. The point here is that when you have a value, you can trust it won't change behind your back.
With pointer semantics, you don't have a value, you have an 'address'. Someone else could alter what is there, you can't know.
Pointer Semantics in C++ :
void foo(Bar * b) ...
... b->bar() ...
You need an * to ask for pointer semantics and -> to call methods on the pointee.
Implicit Pointer Semantics in Java :
void foo(Bar b) ...
... b.bar() ...
Since you don't have the choice of using value semantics, the * isn't needed nor the distinction between -> and ., hence the implicit.

- 9,459
- 4
- 40
- 32
Basically, value semantics means that assigning one value to another creates a copy:
int x = 1;
int y = x;
x = 2; // y remains the same!
A special case is a function call which gets passed an argument:
void f(int x) {
x = 5;
}
int a = 1;
f(a);
// a is still 1
This is actually the same for Java and C++. However, Java knows only a few primitive types, among them int
, double
, boolean
and char
, along with enums which behave in this manner. All other types use reference semantics which means that an assignment of one value to another actually redirects a pointer instead of copying the underlying value:
class Foo {
int x;
public Foo(int x) { this.x = x; }
}
Foo a = new Foo(42);
Foo b = a; // b and a share the same instance!
a.x = 32;
//b.x is now also changed.
There are a few caveats however. For example, many reference types (String
, Integer
…) are actually immutables. Their value cannot be changed and any assignment to them overrides the old value.
Also, arguments still get passed by value. This means that the value of an object passed to a function can be changed but its reference can't:
void f(Foo foo) {
foo.x = 42;
}
void g(Foo foo) {
foo = new Foo(42);
}
Foo a = new Foo(23);
f(a);
// a.x is now 42!
Foo b = new Foo(1);
g(b);
// b remains unchanged!

- 530,221
- 131
- 937
- 1,214
-
why the special case? – lightning_missile Jul 26 '15 at 14:12
-
@morbidCode What special case? Argument passing? It’s not actually a special case, it behaves identical to assignment (it just *isn’t* an assignment syntactically). – Konrad Rudolph Jul 26 '15 at 14:15
-
I'm not sure I got it. Do you mean when you pass a to f(x), a copy of a is created, then that copy is asigned the value 5, so when the method returns the copy is gone and the value of the original a stays the same? – lightning_missile Jul 26 '15 at 14:28
-
Just to be clear, since you and other answers said references are passed by value, while g(Foo) is executing, does b actually have two pointers pointing to it, One already pointing to the original b and another one created inside g(foo)? Same goes for ffoo( and a? – lightning_missile Jul 26 '15 at 14:42
-
@morbidCode My answer doesn’t contradict those other answers. `b` doesn’t have two pointers pointing to it, because it is *itself* a pointer (well actually a reference). So both `b` and (inside `g`) `foo` refer/point to the same object. – Konrad Rudolph Jul 26 '15 at 15:00
-
1I got it at last! Thanks. – lightning_missile Jul 26 '15 at 15:17
Java uses implicit pointer semantics
on variable access (you can not directly edit the reference, it autmatically (implicit) gets resolved to the Object on access) and also uses Pass-by-Value semantics
on method parameters passing.
Read Pass-by-value semantics in Java applications:
In Java applications, when an object reference is a parameter to a method, you are passing a copy of the reference (pass by value), not the reference itself. Note that the calling method's object reference and the copy are pointing to the same object. This is an important distinction. A Java application does nothing differently when passing parameters of varying types like C++ does. Java applications pass all parameters by value, thus making copies of all parameters regardless of type.
Short: All parameters in Java are passed by value. But that doesn't mean an Object gets copied (like the default in PHP4), but the reference to that object gets copied.
You'll see all explanations and in-depth examples on Pass-by-value semantics in Java applications

- 16,433
- 7
- 64
- 79

- 6,191
- 34
- 52
Java is pass by value. C++ can use both, value and reference semantics.

- 46,179
- 22
- 132
- 191

- 6,498
- 3
- 24
- 19
-
4That description is misleading because of Java's hidden pointers (even if the pointers themselves are passed by value.) – finnw Oct 03 '08 at 10:36
-
2@finnw : I agree, but then, Java developers should still understand it that way, because if they hope to change the pointed data inside a function, they will be surprised the original "reference" outside is left untouched. So this is important for them to understand their "references" are copied. – paercebal Oct 03 '08 at 10:58
-
1Bartosz: glad to see people spreading my article ;) finnw: "Hidden" is the key word there... We're talking about how someone programs in Java.Implementation mechanics behind the scenes don't change the fact that Java is strictly pass-by-value -- read the Java Language Spec to see it spelled out. – Scott Stanchfield Oct 03 '08 at 14:50
-
@ScottStanchfield: Would it satisfy you to say that Java, while technically "pass by value", doesn't give programmers the values they really care about? The only values in Java are primitives and references. – isekaijin Mar 29 '15 at 21:36
-
@EduardoLeón - not sure what you mean. Programmers will get the values, but they're limited in how they can use them (that's the difference - with pass-by-value, they cannot modify the values; they can only read the primitives or follow the pointers...) – Scott Stanchfield Apr 02 '15 at 20:58
-
@ScottStanchfield: Say I am writing a program in which I need to manipulate 2D points, given their XY coordinates. When I manipulate a 2D point, the values I really care about are the XY coordinates themselves! However (with the honorable exception of primitives), the only values Java gives me direct, first-class access to are object identities, which are just a reification of when and by whom objects happened to be constructed. Java is pass-by-value, but `new Point(2,3) == new Point(2,3)` does not really compare values I care about. – isekaijin Apr 02 '15 at 21:29
-
@ScottStanchfield: tl;dr: Java is pass-by-value, but when object identities are the only values you have access to, you are effectively programming in a pass-by-reference language. – isekaijin Apr 02 '15 at 21:32
-
@EduardoLeón - Just because a given programmer (you, in this case) doesn't care about something doesn't mean it doesn't matter... Pass-by-reference means that you can change the (in your terms) object identities (in my terms, pointers) - in other words, you can write something like the swap() method I mention in my article. In C++, and Pascal (among others), the compiler gives an _additional_ parameter mode that C and Java do not have - pass-by-reference, which allows people to write code like that swap(), which can be useful for some designs. – Scott Stanchfield Apr 06 '15 at 20:27
-
I'm not saying Java is not pass-by-value. I'm acknowledging it is. What I'm saying is that the values Java gives me are values I find it extremely hard to care about. Examples of languages that give the programmer values he can actually care about are ML and Haskell, where value equality is structural, unless you explicitly use reference cells. In short, what I want from a language with value semantics is equational reasoning, which even C++, for all its faults, manages to give me to some extent. But not Java. – isekaijin Apr 06 '15 at 20:33