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?
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.
-
19
-
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)– MarkJCommented Aug 14, 2013 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 achar[]
) 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...– supercatCommented Jan 8, 2014 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.– supercatCommented Jan 8, 2014 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. Commented May 11, 2017 at 17:40
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
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.
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;
}
-
I thought I might add that it could be seen as similar to a const Dog*– EladianCommented Aug 20, 2015 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. Commented Aug 20, 2015 at 20:31
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 afinal
reference in Java is nullable.