In Java, when I do
Foo bar = new Foo();
bar will be a variable containing the address of the newly constructed object. My professor call it a reference variable
The previous line is equivalent to this in C++:
Foo *bar = new Foo();
here, bar is a pointer to the object
So, is it true that a reference variable in Java is basically a pointer?
Also, when I do this in C++:
Foo bar;
is bar also a pointer? If not, then does that mean there is a difference in memory structure between
Foo bar;
and
Foo *bar = new Foo();
?
Pointers in C++ behave similarly to references in Java.
However, Foo bar; is very different from Foo *bar = new Foo();. The first creates an instance of Foo with automatic duration. It will be destroyed at the end of the block in which it is created. The second creates a dynamically allocated instance of Foo. It will stick around until it is explicitly deleted.
The first can't be used if you want the object to exist after the function returns. If you use a pointer or a reference to it after the function returns, bad things will happen. In that situation, you have to use the second form.
The advantage of the first form is that you don't have to worry about memory management. It will be automatically destroyed at the end of its scope. With the second form, you have to manually delete it, or manage it with a smart pointer of some kind.
If you wonder whether the term "pointer" is appropriate for each language, given each language's specification, then yes.
In the Java language specification, Java references are called "pointers":
An object is a class instance or an array.
The reference values (often just references) are pointers to these objects, and a special null reference, which refers to no object.
In the C++ language specification (which is an international ISO standard, the C++ standard), C++ pointers are called "pointers".
So, is it true that a reference variable in Java is basically a pointer?
--> In short YES! But as c++ allow you to manipulate pointers, java does not. (Similar would be good word to differentiate)
Foo bar; // bar is allocated on stack in c++
--> In java this is just declaration of bar of type Foo.
In c++ objects can be saved on stack as well as on heap while in Java objects are stored only on heap while object references pointing to objects are on stack.
Foo *bar = new Foo(); // C++ : *bar is on stack while memory allocated is on heap
Foo bar = new Foo(); // Java : bar on stack and object created using new is on heap
Also, when I do this in C++:
Foo bar; is bar also a pointer? If not, then does that mean there is a
difference in memory structure between
Foo bar;
It isn't a pointer. It is just an object created on the stack.
In Java all objects are references or pointers, or returns an address using new
The difference between C++ pointers and Java "pointers" is that you can't have pointer arithmetic in Java.
And last time I read The Java Programming Language, it says references are pointers.
Well, if you want to be picky they are actually not exactly like pointers:
Pointer arithmetic is not allowed with Java pointers. You cannot increment, decrement, multiply, etc pointers to move what they point to in memory.
Not Strongly typed. In C, you can cast a pointer from one type to pretty much any type wth no consequence (as long as you are careful). In Java, you will get an exception if you try to cast between incompatible types.
Otherwise they behave pretty much the same way as pointers, and as long as you do not need any of the above features of C-style pointers, you will probably not notice a difference.
A pointer is a value that represents a memory address.
A reference is a value that refers to an object.
Pointers are one way to realize references. In fact, there are several ways to use pointers to realize references, because most objects take up more than one address, so you have to define to which address the reference points.
A few differences:
You can do math with pointers, because adresses are integer values. A reference value has no inherent meaning, it just represents an object.
A pointer can point to any value, eg., a field in an object; a reference always represents the entire object.
It would be more accurate to compare them to Pascal pointers. They have many of the same characteristics: strongly typed, no arithmetic, can be null.
Related
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 2 years ago.
Arrays are not a primitive type in Java, but they are not objects either, so are they passed by value or by reference? Does it depend on what the array contains, for example references or a primitive type?
Everything in Java is passed by value. In case of an array (which is nothing but an Object), the array reference is passed by value (just like an object reference is passed by value).
When you pass an array to other method, actually the reference to that array is copied.
Any changes in the content of array through that reference will affect the original array.
But changing the reference to point to a new array will not change the existing reference in original method.
See this post: Is Java "pass-by-reference" or "pass-by-value"?
See this working example:
public static void changeContent(int[] arr) {
// If we change the content of arr.
arr[0] = 10; // Will change the content of array in main()
}
public static void changeRef(int[] arr) {
// If we change the reference
arr = new int[2]; // Will not change the array in main()
arr[0] = 15;
}
public static void main(String[] args) {
int [] arr = new int[2];
arr[0] = 4;
arr[1] = 5;
changeContent(arr);
System.out.println(arr[0]); // Will print 10..
changeRef(arr);
System.out.println(arr[0]); // Will still print 10..
// Change the reference doesn't reflect change here..
}
Your question is based on a false premise.
Arrays are not a primitive type in Java, but they are not objects either ... "
In fact, all arrays in Java are objects1. Every Java array type has java.lang.Object as its supertype, and inherits the implementation of all methods in the Object API.
... so are they passed by value or by reference? Does it depend on what the array contains, for example references or a primitive type?
Short answers: 1) pass by value, and 2) it makes no difference.
Longer answer:
Like all Java objects, arrays are passed by value ... but the value is the reference to the array. So, when you assign something to a cell of the array in the called method, you will be assigning to the same array object that the caller sees.
This is NOT pass-by-reference. Real pass-by-reference involves passing the address of a variable. With real pass-by-reference, the called method can assign to its local variable, and this causes the variable in the caller to be updated.
But not in Java. In Java, the called method can update the contents of the array, and it can update its copy of the array reference, but it can't update the variable in the caller that holds the caller's array reference. Hence ... what Java is providing is NOT pass-by-reference.
Here are some links that explain the difference between pass-by-reference and pass-by-value. If you don't understand my explanations above, or if you feel inclined to disagree with the terminology, you should read them.
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/topic/com.ibm.xlcpp8a.doc/language/ref/cplr233.htm
http://www.cs.fsu.edu/~myers/c++/notes/references.html
Related SO question:
Is Java "pass-by-reference" or "pass-by-value"?
Historical background:
The phrase "pass-by-reference" was originally "call-by-reference", and it was used to distinguish the argument passing semantics of FORTRAN (call-by-reference) from those of ALGOL-60 (call-by-value and call-by-name).
In call-by-value, the argument expression is evaluated to a value, and that value is copied to the called method.
In call-by-reference, the argument expression is partially evaluated to an "lvalue" (i.e. the address of a variable or array element) that is passed to the calling method. The calling method can then directly read and update the variable / element.
In call-by-name, the actual argument expression is passed to the calling method (!!) which can evaluate it multiple times (!!!). This was complicated to implement, and could be used (abused) to write code that was very difficult to understand. Call-by-name was only ever used in Algol-60 (thankfully!).
UPDATE
Actually, Algol-60's call-by-name is similar to passing lambda expressions as parameters. The wrinkle is that these not-exactly-lambda-expressions (they were referred to as "thunks" at the implementation level) can indirectly modify the state of variables that are in scope in the calling procedure / function. That is part of what made them so hard to understand. (See the Wikipedia page on Jensen's Device for example.)
1. Nothing in the linked Q&A (Arrays in Java and how they are stored in memory) either states or implies that arrays are not objects.
Arrays are in fact objects, so a reference is passed (the reference itself is passed by value, confused yet?). Quick example:
// assuming you allocated the list
public void addItem(Integer[] list, int item) {
list[1] = item;
}
You will see the changes to the list from the calling code. However you can't change the reference itself, since it's passed by value:
// assuming you allocated the list
public void changeArray(Integer[] list) {
list = null;
}
If you pass a non-null list, it won't be null by the time the method returns.
No that is wrong. Arrays are special objects in Java. So it is like passing other objects where you pass the value of the reference, but not the reference itself. Meaning, changing the reference of an array in the called routine will not be reflected in the calling routine.
Everything in Java is passed by value .
In the case of the array the reference is copied into a new reference, but remember that everything in Java is passed by value .
Take a look at this interesting article for further information ...
The definitive discussion of arrays is at http://docs.oracle.com/javase/specs/jls/se5.0/html/arrays.html#27803 . This makes clear that Java arrays are objects. The class of these objects is defined in 10.8.
Section 8.4.1 of the language spec, http://docs.oracle.com/javase/specs/jls/se5.0/html/classes.html#40420 , describe how arguments are passed to methods. Since Java syntax is derived from C and C++, the behavior is similar. Primitive types are passed by value, as with C. When an object is passed, an object reference (pointer) is passed by value, mirroring the C syntax of passing a pointer by value. See 4.3.1, http://docs.oracle.com/javase/specs/jls/se5.0/html/typesValues.html#4.3 ,
In practical terms, this means that modifying the contents of an array within a method is reflected in the array object in the calling scope, but reassigning a new value to the reference within the method has no effect on the reference in the calling scope, which is exactly the behavior you would expect of a pointer to a struct in C or an object in C++.
At least part of the confusion in terminology stems from the history of high level languages prior to the common use of C. In prior, popular, high level languages, directly referencing memory by address was something to be avoided to the extent possible, and it was considered the job of the language to provide a layer of abstraction. This made it necessary for the language to explicitly support a mechanism for returning values from subroutines (not necessarily functions). This mechanism is what is formally meant when referring to 'pass by reference'.
When C was introduced, it came with a stripped down notion of procedure calling, where all arguments are input-only, and the only value returned to the caller is a function result. However, the purpose of passing references could be achieved through the explicit and broad use of pointers. Since it serves the same purpose, the practice of passing a pointer as a reference to a value is often colloquially referred to a passing by reference. If the semantics of a routine call for a parameter to be passed by reference, the syntax of C requires the programmer to explicitly pass a pointer. Passing a pointer by value is the design pattern for implementing pass by reference semantics in C.
Since it can often seem like the sole purpose of raw pointers in C is to create crashing bugs, subsequent developments, especially Java, have sought to return to safer means to pass parameters. However, the dominance of C made it incumbent on the developers to mimic the familiar style of C coding. The result is references that are passed similarly to pointers, but are implemented with more protections to make them safer. An alternative would have been the rich syntax of a language like Ada, but this would have presented the appearance of an unwelcome learning curve, and lessened the likely adoption of Java.
In short, the design of parameter passing for objects, including arrays, in Java,is esentially to serve the semantic intent of pass by reference, but is imlemented with the syntax of passing a reference by value.
Kind of a trick realty... Even references are passed by value in Java, hence a change to the reference itself being scoped at the called function level. The compiler and/or JVM will often turn a value type into a reference.
Before I post my question, I have read the following excellent articles on java-pass-by-value.
I am convinced I have understood it well.
Is Java "pass-by-reference" or "pass-by-value"?
http://www.javaworld.com/article/2077424/learn-java/does-java-pass-by-reference-or-pass-by-value.html
My question has to do with a side-by comparison of Java with other language that supports pass-by-reference(C++ may be).
In case of Java, you have a handle (reference) pointing to the object in location A. so object itself could be modified. But It is not possible to change the object location itself.
I.e An object stored in memory address 0X945 cannot be changed to 0X948.
In languages such as C++, you can choose to pass-by-value or pass-by-reference. (It is in the hands of the programmer correct?). Hence it is possible to change the location of object in memory space correct?
P.S: I have good background on Java but on C++. so my views above may be wrong.
It is claimed in the article 1, I cited above that there is no notion of pointers in Java. I dont know how far that is true? (why do NullPointerException exists then)
EDIT:
consider this example:
void swap(Object A,Object B) {
Object temp=B;
Object B=A;
Oject A=temp;
}
when I call the method in Java such as swap(A,B), nothing happens
but in C++ (I presume), swap happens. which probably means I am changing the location of objects in memory correct?
In java even - references to objects are passed by value. i.e, everything is pass-by-value. Next,
you can choose to pass-by-value or pass-by-reference. (It is in the hands of the programmer correct?).
Correct. But you can't do it in Java.
An object stored in memory address 0X945 cannot be changed to 0X948.
You can't do this in both java and C++.
NullPointerException is thrown when you try to access a property / method of something which doesn't exist (is null). i.e, the reference points to null when an instance of the object is required.
Object o = null;
o.toString() --> NPE. o points to null.
so in C++, do pass-by-reference means you pass the object itself, so that it could be reassigned in swap method
In C++, pass by reference, swap(Object &A, Object &B) appears to be close to java's pass by value.
In Java Object A is a reference to an Object and is null by default. As Object is already a reference and so when this reference is copied, it is passed by value.
In C++, Object A is an instance of an Object and is always a unique object. As Object is an instance, you are passing by reference using Object& because the Object is not passed, but a reference to it.
Java is always pass by value, it's just when you are passing objects, the value passed is the location in memory so it can act like pass by reference.
when I call the method in Java such as swap(A,B), nothing happens but
in C++ (I presume), swap happens.
No it doesn't. "Nothing" also happens in C++.
A correct translation of the code to C++ would be:
void swap(Object *A,Object *B) {
Object *temp=B;
B=A;
A=temp;
}
(Yes, the syntax for types is different between the languages. Namely, the pointer-to-Foo type is written as Foo * in C++ and Foo in Java; that's just a syntactical difference between the languages.)
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 9 years ago.
I’ve read a lot of articles about how “pass-by-reference” doesn’t exist in Java since a copy of the value of the reference is passed, hence “pass-by-copy-of-reference-value”.
The articles also say a reference value is a pointer.
(So pointers do exist in Java.)
Some other articles say: Java has no pointers.
So what is the correct solution?
How does a pointer differ from a reference (or reference value), and do they exist in Java?
They aren't like C pointers. There's no pointer arithmetic allowed.
Java has only one mechanism for passing parameters: pass by value in all cases. For primitives, the value is passed. For objects, the reference to the object on the heap is passed.
A pointer is a reference type; it refers to something. What you're basically asking is: "Does Java have Dobermans? Because some articles say it has dogs."
As noted in Wikipedia entry for Pointer:
A pointer is a simple, more concrete implementation of the more abstract reference data type. Several languages support some type of pointer, although some have more restrictions on their use than others
It goes on to say this about Java specifically:
Unlike C, C++, or Pascal, there is no explicit representation of pointers in Java. Instead, more complex data structures like objects and arrays are implemented using references. The language does not provide any explicit pointer manipulation operators. It is still possible for code to attempt to dereference a null reference (null pointer), however, which results in a run-time exception being thrown. The space occupied by unreferenced memory objects is recovered automatically by garbage collection at run-time.
Looking up Reference you find:
In computer science, a reference is a value that enables a program to indirectly access a particular datum, such as a variable or a record, in the computer's memory or in some other storage device. The reference is said to refer to the datum, and accessing the datum is called dereferencing the reference.
A reference is distinct from the data itself. Typically, a reference is the physical address of where the data is stored in memory or in the storage device. For this reason, a reference is often called a pointer or address, and is said to point to the data. However a reference may also be the offset (difference) between the datum's address and some fixed "base" address, or an index into an array.
Java chose to use the broader term "reference" instead of "pointer" because of the differences between Java and C. (Thus creating a sisyphus-like situation where we have to keep explaining that Java is pass-by-value).
You don't have a C pointer, you have a Java Reference. This has nothing to do with a C++ reference, or pass-by-reference.
Because Java is pass-by-value it is similar to using a C pointer in that when you pass it to a method, the value (e.g. memory address) is copied.
It is right to say both:)
Java has no pointers since java has simplified pointers as references.
Object o=new Object();
We got an object o here; o is actually a pointer.
Basically, pointers and references are the same thing; they point to (refer to) something else in memory. However, you cannot do integer arithmetic on references. You may find some pages on this slide useful:
http://www.cis.upenn.edu/~matuszek/cit594-2005/Lectures/15-pointers-and-references.ppt
You have to get your head around the different, but related concepts of types, variables and objects. If we ignore for now the fundamental types like int and only consider class types, then in Java there are variables, which are "named things", and objects. Both variables and objects have a type. However, a variable of type T is not an object; rather, it is a mechanism for locating an object of type T, and for informing the runtime that this object is in use. A variable may at any point not locate any object, in which case it is null, or it may, and in that case the very existence of the variable keeps the object alive.
Let's repeat: Variables have names. Objects don't have names. Variables are not objects.
When you pass a variable as an argument into a function call, the corresponding function parameter becomes duplicate of the argument, so that there are now two variables which both locate the same object. When you assign one variable to another, you make the left-hand variable locate the same object (possibly null) as the right-hand variable, relinquishing the possibly previously held location. But no objects are being affected by this; the objects exist in some unrelated, unprobable plane of existence.
Also, variables have a deterministic lifetime, which is determined by their scope (essentially block-local or static-global). The lifetime of variables is non-deterministically related to the lifetime of objects, but the lifetime of objects cannot be controlled directly.
That's the type system and object model of Java (for class types) in a nutshell. It's up to you what you want to label this; it makes sense to say that "variables are references", since that's what they do, but you might as well just stop trying to compare yourself to other languages and just say "variables", which is clear enough within the context of Java. Variables are variables, objects are objects, neither one is ever the other, and you need the former to talk about the latter.
In Java, a reference is a pointer, usually one that isn't null. That's why it's called NullPointerException, not NullReferenceException. "The reference values (often just references) are pointers to these objects, and a special null reference, which refers to no object. "
Java pointers/references are akin to Pascal pointers, not to C or C++ pointers, in that they are very strongly typed and do not support address arithmetic.
So I've been thinking (while reading this Java pdf)...
I know this may seem silly but why can't I do this in c++.
float &f = new float;
Isn't this saying the reference of f is the address of new float?
In Java, I see something like this
String s = new String("something")
String s is called a string reference.
Does the word 'reference' in Java have the same meaning as in C++?
Java references are much closer to C++ pointers rather than C++ references. In Java, you can do the following with a reference:
Change which object it refers to
Check whether two references are equal or unequal
Send messages to the referenced object.
In C++, pointers have these same properties. As a result, the code you're looking for in C++ is something like
float* f = new float;
Which is perfectly legal. For a better comparison, this Java code:
String myString = new String("This is a string!"); // Normally I wouldn't allocate a string here, but just for the parallel structure we will.
System.out.println(myString.length());
/* Reassign myString to point to a different string object. */
myString = new String("Here's another string!");
System.out.println(myString.length());
would map to this C++ code:
std::string* myString = new std::string("This is a string");
std::cout << myString->length() << std::endl;
delete myString; // No GC in C++!
/* Reassign myString to point to a different string object. */
myString = new std::string("Here's another string!");
std::cout << myString->length() << std::endl;
delete myString; // No GC in C++!
Hope this helps!
No in Java when you declare String s, s doesnt contain the address of the new String, but its value which in this case is something.
You can take a look at this post for more information about variable address locations in Java which is kind of meaningless.
In C++ you use pointers so if you have:
int foo = 0;
you can then have a pointer refer to the address of foo with:
int* bar = &foo;
This line of code says that the value of bar is foo's memory address.
Java manipulates objects by reference and every object is a reference but it also collects garbage automatically. If you use the new keyword in C++ you need to clean up the memory yourself:
float* f = new float(0); // Allocate memory
...
delete f; // Free memory
Yes, I agree with Joni, a c++ pointer is syntactically closer to a reference in Java.
The other important difference between a pointer and a reference in C++, a pointer can either point to a real object or it can be equal to null. A reference in C++, by definition, always points to a real object or variable. You must assign it to something real when you declare it.
To answer your question, for best practices only use the new or malloc operator to allocate space. Assuming that you are new to pointers, The big difference between pointers and references is that you must use an explicit operator-the * operator-to dereference a pointer, but you don't use an operator to dereference a reference.
Java parameters are close to C++ references. For instance;
When you are passing an object, actually you are passing a reference value. Therefore all objects are references in Java.
On the other hand, Java pass methods by value.
You can also check this link out.
In java reference, you can refer values or methods more than one times. But in c++,you can refer only one value in a single reference variable. So in java reference variables are more likely pointers of c++.Moreover java runs garbage collector automatically, so there is no use of delete key which is used in c++ to release memory.
What's your deep comprehension of pointer,reference and Handle in C,C++ and Java?
We usually think about the pointer,reference and Handle on the specify language level, it's easy to make confusion by the newbie like me.
Actually all those concept in java, just a encapsulation of pointer.
All pointer just a encapsulation of main memory addresses .
So all of those ,just a encapsulation wiles.
all above, it's my personal glimpse. And what's your comprehension ?
welcome to share with me.
Each language has differences to this respect. In C there are only pointers that are variables holding a memory address. In C you can use pointer arithmetic to move through memory, if you have an array, you can get a pointer to the first element and navigate the memory by incrementing the pointer.
Java references are similar to pointers in that they refer to a location in memory, but you cannot use pointer arithmetic on them. Only assignments are allowed. Note that the reference is not the object, but a way of accessing an object. This can be seen in argument passing semantics: objects are not passed by reference, references are passed by value:
public static void swap( Object o1, Object o2 )
{
Object tmp = o1;
o1 = o2;
o2 = tmp;
}
The previous piece of code is a complex no-op. References to two objects are passed by value, they are played with inside the method and nothing happens from the caller perspective: the real objects do not suffer any change, nor do the references the caller has into those objects. That is, if the call is swap( ref1, ref2 ), the system will make copies of the references into o1 and o2, the copies are changed within the method, but the caller variables ref1 and ref2 will remain unchanged after the method call.
In C++ you have two concepts: pointers are the same as C pointers and close to Java references, while C++ references are aliases into the objects they refer. C++ references can only be initialized with one object/data element in construction and from there on, using the original object and the reference is exactly the same. Besides the fact that references don't hold the resource and thus the destructor will not be called when the reference goes out of scope, nor will the reference notice if the referred object is destroyed, for all other uses the two names are the same element.
template <typename T>
void swap( T & a, T & b )
{
T tmp( a );
a = b;
b = tmp;
}
The code above in C++ differs from the Java version in that it does change the caller objects. If a caller uses swap( var1, var2 ), then the references are bound to those variables, and it is var1 and var2 the ones that suffer the change. After the call, the value of var1 and var2 is actually swapped.
Handles are in a different level, they are not language construct but tokens provided by a library so that you can later on refer to some resource that the library manages internally. The most general case are integer handles that are ids (or offsets) into a resource table, but I have seen strings used as handles. It is the library internally who decides what is exactly a handler (a pointer, an integer, a string or a more complex data structure). Handles are meant to be opaque in that the only sensible use is to store them and later give it back to the same library as part of other function signatures.
In C++ a pointer is a variable that points to a location in memory. You can access the object or data stored there by dereferencing the pointer. A reference is simply a pointer that has two distinctions from a pointer. First, you cannot change what a reference points to once the reference is initialized. Second the dereferencing semantics are removed so you can access a reference as if it were an object allocated on the stack instead of on the heap with new.
In Java, there are no pointers, only references. Every object you use is a reference to an object allocated on the heap. The downside is you can't do pointer math tricks. That's also the upside.
EDIT:
As pointed out in the comments, a Java reference differs from a C++ reference in that it can be reassigned once initialized. They are still called 'reference types' by the language specification, but behaviorally they act like pointers in terms of being able to be reassigned and passed to functions, but the semantics of dereferencing them look like non-pointer access looks in C++.