107

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
  • 12
    note C++ also has references which are different to pointers or java references
    – jk.
    Commented Mar 28, 2012 at 8:17
  • @jk. I thought it would be the same as in Java.What's the difference?
    – Gnijuohz
    Commented Mar 28, 2012 at 8:20
  • 19
    C++ 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). Commented Mar 28, 2012 at 8: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
    Commented Jul 13, 2016 at 16:52

4 Answers 4

152

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.

8
  • 19
    +1 for might. Don't rely on implementation details.
    – user
    Commented Mar 28, 2012 at 9:52
  • 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
    Commented 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 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
    Commented 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.
    – supercat
    Commented 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.
    – Lew Bloch
    Commented May 11, 2017 at 17:40
7

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

5

Java References and C pointers differ in exactly two points:

  1. There's no pointer-arithmetic for the former.
  2. 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.

-1

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;
}
2
  • I thought I might add that it could be seen as similar to a const Dog*
    – Eladian
    Commented Aug 20, 2015 at 14:32
  • 2
    You 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

Not the answer you're looking for? Browse other questions tagged or ask your own question.