C has pointers and Java has what is called references. They have some things in common in the sense that they all point to something. I know that pointers in C store the addresses they point to. Do reference also store the address? How they are different except that pointer is more flexible and error-prone?
-
12note C++ also has references which are different to pointers or java references – jk. Mar 28 '12 at 08:17
-
@jk. I thought it would be the same as in Java.What's the difference? – Gnijuohz Mar 28 '12 at 08:20
-
19C++ references aren't rebindable (i.e. you can't change the object designated) and aren't nullable (i.e. you can't validly have them reference no object at all). – AProgrammer Mar 28 '12 at 08:37
-
@Gnijuohz Rephrasing what @AProgrammer said: A `final` reference in Java is _nearly_ equivalent to a C++ reference. The reason that they are not _exactly_ equivalent is, a C++ reference is additionally not nullable, whereas a `final` reference in Java is nullable. – Utku Jul 13 '16 at 16:52
4 Answers
References might be implemented by storing the address. Usually Java references will be implemented as pointers, but that's not required by the specification. They may be using an additional layer of indirection to enable easier garbage collection. But in the end it will (almost always) boil down to (C-style) pointers being involved in the implementation of (Java-style) references.
You can't do pointer arithmetic with references. The most important difference between a pointer in C and a reference in Java is that you can't actually get to (and manipulate) the underlying value of a reference in Java. In other words: you can't do pointer arithmetic.
In C you can add something to a pointer (i.e. the address) or substract something to point to things that are "nearby" or point to places that are at any place.
In Java, a reference points to one thing and that thing only. You can make a variable hold a different reference, but you can't just ask it to point to "the thing after the original thing".
References are strongly typed. Another difference is that the type of a reference is much more strictly controlled in Java than the type of a pointer is in C. In C you can have an int*
and cast it to a char*
and just re-interpret the memory at that location. That re-interpretation doesn't work in Java: you can only interpret the object at the other end of the reference as something that it already is (i.e. you can cast a Object
reference to String
reference only if the object pointed to is actually a String
).
Those differences make C pointers more powerful, but also more dangerous. Both of those possibilities (pointer arithmetic and re-interpreting the values being pointed to) add flexibility to C and are the source of some of the power of the language. But they are also big sources of problems, because if used incorrectly they can easily break assumptions that your code is built around. And it's pretty easy to use them incorrectly.

- 10,956
- 3
- 52
- 45
-
18
-
2+1 Doesn't garbage collection deserve mention as a specific bold point? It's another way that C pointers are more powerful but also more dangerous (risk of dangling pointers to freed memory causing memory corruption, risk of memory leaks) – MarkJ Aug 14 '13 at 11:07
-
Another difference between references and pointers is that a pointer in C may be converted into a sequence of numbers (e.g. by using `memcpy` to move one into a `char[]`) and vice versa. If a pointer is converted to a sequence of numbers which is stored someplace (maybe shown on screen and copied down by the operator on a slip of paper), all copies of the pointer within the computer are destroyed, and that sequence of numbers is converted back to a pointer (perhaps after being typed in by the operator), the pointer must still point to the same thing it did before. A program which... – supercat Jan 08 '14 at 19:22
-
...displayed a pointer as numbers, and then converted manually-entered numbers to a pointer, might be "evil", but it would not invoke any Undefined Behavior unless the operator typed in numbers that hadn't been shown to form a valid pointer. General-purpose garbage collection is thus impossible in fully portable C, because there's no way the computer can know whether a copy of a pointer might exist somewhere in the universe. – supercat Jan 08 '14 at 19:24
-
According to the JLS, §4.3.1, references in Java are pointers, so "Usually Java references will be implemented as pointers, but that's not required by the specification." is false. – Lew Bloch May 11 '17 at 17:40
-
@LewBloch: well, "pointer" is a very loaded term, as the existence of this question proves. And a reference is a "pointer" in some sense (it can be used to refer to and interact with an object), but not in other senses of the word (it is very clearly not the same thing as a C pointer). And the existence of that single line also doesn't mean that references must always be implemented using C-style pointers in a VM. – Joachim Sauer May 11 '17 at 17:43
-
Um, it's not about the implementation, it's about the semantics. Java's "references" have the semantics of pointers, regardless of how they're implemented. "Pointer" isn't a "loaded" term, it's objectively verifiable. – Lew Bloch May 11 '17 at 17:45
-
The sentence you're critiquing explicitly talks about how they are implemented and now you say it's not about implementation. I don't quite understand what your criticism is about now. Also, please re-read the question. It is explicitly how a pointer in C differs from a reference in Java and how the later is implemented. Using "pointer" here to mean anything other than "pointer as used C" is highly measleading – Joachim Sauer May 11 '17 at 17:47
C++ references are different again.
They have to be initialized and can't be null (at least not in a well formed program) and can't be reseated to refer to something else. a C++ reference is much more like an alias for an object.
Another important difference between pointers and Java/C++ references is that you can take the address of a pointer you cannot access the address of a reference (indeed a C++ reference need not actually exist as an object in memory at all) consequently you can have a pointer to a pointer but not a reference to a reference

- 10,216
- 1
- 33
- 43
Java References and C pointers differ in exactly two points:
- There's no pointer-arithmetic for the former.
- And you cannot create a Java reference to whatever you want, you can only copy those saved somewhere accessible (static fields, fields of objects, local variables) or returned by function-invocations (like constructor-calls), which thus all refer to Java objects (never to basic types like references,
char
,int
and so on).
Someone wrote that References are strongly typed, because you cannot force the compiler to treat an int*
as a char*
.
Completely aside from the fact that that particular conversion is actually safe, there is no polymorphism in C, so that comparison is a non-starter.
Certainly, Java is more strongly-typed than C, not that that's a feature of C pointers vs Java references, you need to use the JNI to break type-safety (aside from disregarding generic restrictions), but even in C you have to force the compiler.
Someone wrote that Java references might be implemented as C pointers, to which I say sure, as they are strictly less powerful, on 32Bit machines they typically are, if the JVM is implemented in C. Though on 64Bit machines, they are normally compressed ordinary-object-pointers ("compressed OOPs") to save space and bandwidth.
Anyway, those C pointers need not be equivalent to hardware addresses either, even if they typically (>99% of implementations) are for performance reasons.
Finally, that's an implementation detail which is not exposed to the programmer.

- 8,591
- 5
- 31
- 50
They are slightly different. In Java a copy of the reference is copied to the stack of a called function, pointing to the same object as the calling function and allowing you to manipulate that object. However you cannot change the object the calling function refers to.
Consider the following java code
public static void changeRValue(StringBuffer sb){
sb = new StringBuffer("helllllo"); /*attempt to assign the reference
to a new object*/
}
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("hi"); //Create a new string buffer
changeRValue(sb); //Call changeRValue
System.out.println(sb.toString()); //Prints "hi" not "hello"
}
Now consider a pointer in c++:
void func(Dog* dog){
*dog = Dog("hello world"); //Change the value of dog to a new object
}
int main(int argc, const char * argv[]) {
Dog dog1("hi"); //Create a dog object
func(&dog1); //pass the address of dog
cout << dog1.name; //Prints "hello world" not hi.
return 0;
}

- 115
- 1
-
I thought I might add that it could be seen as similar to a const Dog* – Eladian Aug 20 '15 at 14:32
-
2You can modify the pointed-to object in Java with the same ease as in C++. You just need to have access to the right members. Java objects don't have assignment-operators because Java does not support user-defined operator-overloading, so you cannot use an overloaded operator, big deal. That lack of Java has nothing to do with the fact that Java references are the same as C++ pointers bereft of pointer-arithmetic. – Deduplicator Aug 20 '15 at 20:31