This question already has answers here:
Does Java have pointers?
(12 answers)
Closed 8 years ago.
I recently read this post: Is Java "pass-by-reference" or "pass-by-value"?
The first answer was far too terse and specific to give me a firm understanding, and everyone else created 15 page essays explaining what should be a simple topic. Are the following rules correct (which are pretty simple if true):
1.) Named things associated with a type that aren't primitives ("objects references" in Java talk) are pointers in C++.
2.) . on a Java pointer is the same as using -> on a C++ pointer.
3.) = on a Java pointer is the same as using = on a C++ pointer.
4.) All functions pass by value (and hence pass Java pointers by value).
(This ignores memory management differences like the fact that = on a Java pointer is fine whereas = on a C++ pointer means you might need to worry about memory management)
The most confusing element to the puzzle is that no one I have seen has conveyed this set of rules/understanding of what Java is doing in clear English (opting instead for 15 pages and diagrams). The second most confusing element is that Java uses the word "reference" in a way that is different from C++. If you want an analogy between what Java is doing in terms of C++, pointers and the rules I created are the simplest terms to digest Java's behavior.
Point 1 is correct.
Object o = new Object();
Variable o is storing a pointer to where the object is in memory.
Point 2 is also correct.
Object o = new Object();
o.hashCode();
This is calling the method hashCode of the object stored in o.
Point 3, correct again.
Dog d = new Dog();
Dog d2 = new Dog();
System.out.println(d == d2);//This will print false
d2 = d;
System.out.println(d == d2);//This will print true
In the first output d does not equal d2 because the pointers to the objects are different. In the second output d does equal d2 because they both are pointing to the same location.
Point 4 is technically correct.
Primitives are passed by value.
A
When passing objects to a function it is passing a copy of the pointer to the object and not a copy to the object itself. The pointer to the object is being passed by value to the function. Hopefully this snippet can help explain it.
public void example(int i, Object o) {}
public static void main(String[] args) {
Object o = new Object();
example(3, o);//This is passing the number 3 to the function. It also passes by vlue a pointer to where object o is stored in memory.
}
Related
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 7 years ago.
Java is pass-by-value. This means that a called method acts on a copy of an object that was passed in, not on the original object.
If the object is not changed in the method, creating an actual copy seems unnecessary. So a compiler that implements the program to create such a copy would be pretty inefficient. Are all Java compilers (javac, gcj, ECJ, etc.) really doing that?
At least in the case where a parameter is declared final it would make a lot of sense not to copy.
EDIT
OK, so objects are not copied. I got confused because String is special in that it is copied (immutable). Sorry about my unknowings. Just to make up for it, here is a thousandth example of what happens when an object is passed:
import java.lang.System;
class C { int member; }
public class Test {
static void subMethod(C object) { object.member=1; }
public static void main(String[] args) {
C object = new C();
object.member=0;
subMethod(object);
System.out.println(object.member); // prints "1"
}
}
Yes, Java is always pass-by-value. But for objects, it passes the reference value. In other words, the object isn't copied, but its reference is. Changing an object's attributes inside a method changes it outside the method as well.
From here,
However, Objects are not passed by reference. A correct statement would be Object references are passed by value.
On-topic: the compiler simply copies the reference to its chunk of memory in the stack.
Objects in Java are references, and it is this reference which is passed by value; meaning Java is pass-by-reference with objects for practical purposes.
EDIT
It seems my use of the term 'practical purposes' is causing a lot of controversy, so let me clarify. I simply meant that what most people think of when they think of 'pass-by-reference' is that changes to the passed in value are persisted outside of that method, which is the case in Java. e.g.
void someMethod(SomeClass a) {
a.mutateState();
}
SomeClass a = new SomeClass();
someMethod(a); //passes reference to a by value;
a.methodInvolvingSomeState(); //mutations of object state persist to here, as if the previous call were pass-by-reference.
That's all I meant by 'for practical purposes'; OP was under the impression that a copy of a was made, which I was trying to explain was not true. I am fully aware that java is always pass-by-value, hence explicitly stating that it is the reference that is passed by value. As has been pointed out in the comments there are plenty of occasions where it is not the same as if it were actually pass-by-reference, and it was not my intention to indicate that any of those were possible in Java.
Trying to fully grasp Java's pass-by-value. Let's say we have this code:
public class Test {
static void switchIt(Test t) {
t = new Test();
}
public static void main(String ... args) {
Test a = new Test();
switchIt(a);
}
}
When the object referenced by a gets passed to switchIt(), the reference value is copied to t. So we'd have two different reference variables, with identical bit-patterns that point to a single object on the heap.
When t = new Test() runs, obviously a still refers to the old object, and t now points to a new object on the heap. Since the a and t reference variables used to have identical bit-patterns, does this mean that Java implicitly changed the bit-pattern of the t reference variable? Or is it wrong to assume that the bit patterns were ever identical to begin with?
Let's say the a reference variable is represented on the stack as 0001. When I pass it to the function, that means t is also represented on the stack as 0001, since I passed a copy of the bits in the reference variable.
When I assign t to a new Test(), if t and a both are represented as 0001 on the stack, would that 0001 change for t?
Think of it this way:
Java isn't passing the object, it's passing the memory pointer of the object. When you create a new object, it gets a new pointer. So when we say java always passes by value, it's because it's always passing the pointer of the object which is a numeric value.
Even though the objects are equal to one another (a.equals(t)) may return true - they are not identical because they have different pointers and are thusly different objects residing in different memory space.
Using your edit example. a would have 0001 but t would be 0002
Is Java "pass-by-reference" or "pass-by-value"?
Hope that helps
Yes, the reference for t would change to point to the newly-allocated Test instance. Your understanding is correct on that point.
When the switchIt() method returns, there are no longer any references to that new object. It is now eligible for garbage collection, while the original object that a continues to reference will not be collectible until main() returns.
I think you got it, but you didn't phrase it too well. Here's a more in depth explanation, though the implementation may not be 100% exactly as I'm describing.
When you compile that code, a structure called a "stack frame" will be created for each of your methods. Each stack frame will hold enough space in it for parameters, local variables and so on. Basically it will have enough resources for your method to do its thing. All these stack frames are placed in "the stack" :)
When you run your code, in main you create a new instance of Test and assign the reference to variable a or, more precisely, to the location in the stack frame reserved for variable a. The actual object will be stored on the heap and your variable a will only hold the memory address of that object, as you already seem to know.
When you call switchIt, the runtime will send a copy of the reference a to the stack frame of the method switchIt. This stack frame has enough space for your parameter and it will store it in its reserved space. But what you're doing in switchIt is replacing the initial value stored in that reserved space with a new reference from a new object that has just been created and placed on the heap. Now you have two objects on the heap, each stack frame containing one of these references.
I think the code will clear you more .Check the hash code in each print statement it is not the memory location but it will help you to understand the answer of your question.
class Ideone
{
static void switchIt(Ideone t) {
System.out.println("Object t "+t); // print statement 2
t = new Ideone();
System.out.println("object t after changing t "+t); // print statement 3
}
public static void main(String[] args) {
Ideone a = new Ideone();
System.out.println("object a "+a); // print statement 1
switchIt(a);
System.out.println("object a after calling switchIt() "+a); // print statement 4
}
}
Output:
object a Ideone#106d69c
Object t Ideone#106d69c
object t after changing t Ideone#52e922
object a after calling switchIt() Ideone#106d69c
print statement 1,2,4 have same hash code but 3 has different hash code.
1. Creating object a
2. Passing a to switchIt(Ideone t):
3. Changing t to new Ideone():
Note:The hash code are not actual memory location.
I am looking to clarify my knowledge of java:
basketball o, s;
s = new basketball();
o = s;
The question is how many basketball objects are created, 1 or 2? I ran some tests and thought only 1 object was created, as when I modified one, it was reflected in the other. Sorry for the simple question, I was just seeking to clarify this.
only one object is created but 2 referrences are created.Here(basketball o, s;) o and s are just references
But when you did s = new basketball(); then an object is created
and after that when you did o=s then you are just pointing to s but not creating any object
Have a look at this to see different ways of creating objects
Only one object is created here. o and s are just handles to the same object and, as you said yourself, modifying one will modify the other (as they're pointing to the same object).
To understand more clearly, I'd recommend reading How is a Java reference different from a C pointer? and Is Java “pass-by-reference” or “pass-by-value”?
s is the only object created then o references/points to the location of s in memory.
your variables o and s are just references, when you use the operator new AnyObject() then you create your object and it return the reference pointer to whaterver the left hand side varaible.
so you have 2 references and 1 object
and both reference variables point to that object
Since you seem new to java i will explain in detail,
When you write this basketball o, s; in java , it means you are creating two reference variables of type basketball. What a reference variable means is , it is a type of variable that can point to the actual object of basketball.
When you write this s = new basketball(); in java it means, You are creating a new object in java , and assigning that object to the reference variable. This means you are providing a link to the object through s
Imagine this, the reference variable as a remote control and the object (instance variable) as a TV. Although all the real work is done by TV , the control of entire TV is done through the remote control. Its a link to the TV for the user.
so When you do o = s; , you are assigning the object (instance variable) pointed by s to o . Hence now both s and o point to the same object. And hence When changes are made on one it obviously will reflect on the other. Imagine it like having two remote controls for the same TV.
For your answer , Only one object is created , but two references are created.
basketball o, s;
s = new basketball();//Here you create the object after that
o = s;//here you assign the address of 1st object(which is store in s) to o
suppose s = new basketball();
lets take the address of s is 23490.After that we put this address value into o.So o is also pointing the same object.
Hence one object will be created.
this might be stupid question, but:
When I moved from ASM to C (no, I am not actually that old, I just started to love programing on MCU), I LOVED the way heap memory is used. Malloc was my friend, and I quickly became familiar with pointers. BUT...
Than I moved to OOP and Java. And actully, despite I don´t like Java as a runtime, I love its language. Now, I would like to combine both, speed and memory management capabilities of C and the beauty of OOP. So I started to learn C++.
My problem is, in Java I was used to access class members and functions with . operator. In C++, I have to use somehow not so nice and easy to type -> operator.
So, my question is, is there some way you can use . operator instead of -> to access class members of object allocated on heap? Becouse, stack is limited, and the true power of OOP is in dynamic creation of objects. Remaining "differences" are OK :) . Well, maybe C++ yould allow you to define class methods inside class, but no one can have everything, right? :D Thanks.
Class &c = *c_ptr; // dereference pointer
https://isocpp.org/wiki/faq/references
Sure. Just get a reference to some object allocated on the heap (or the stack, but that's beyond scope):
Object* my_obj_ptr = SomehowGetHeapObject();
Object& my_obj = *my_obj_ptr;
...then you can use the dot operator on the reference:
my_obj.Foo();
Perhaps a pertinent question would be, why is this throwing you off?
No, that is not posssible, at least without some syntax changes. You can use (*Pointer).Function, which Pointer->Function is just a synonym for, but I think the latter is more comfirtable (that's why it exists).
EDIT: Or as the other posts say, just store the dereferenced pointer in a reference. Haven't thought about that, as the whole question is a bit strange.
In C++ there are two ways to access members of an object, depending upon how you are holding the object. If you have the object directly (or have a reference to it), you use the dot operator, .. If you have a pointer to the object, you use the pointer operator ->.
Consider:
class C;
...
// creates a new copy of "c" on stack
int f(C c) {
c.something = c.else;
}
// creates a reference to caller's "c"
int f(C& c) {
c.something = c.else;
}
// creates a pointer to caller's "c"
int f(C* p) {
c->something = c->else;
}
So, your problem is this: you have a pointer, but you don't like the pointer operator. Frankly, I don't really see this as a problem, you should just use the pointer operator until you like it. But, this is SO, so here is a solution.
Initialize a reference from your pointer, and use the reference instead:
int f(C* p) {
C& c = *p;
c.something = c.else; // update the object pointed to by 'p'
}
Or, to make it feel even more natural:
int f2(C& c) {
c.something = c.else; // updates f1's object
}
int f1() {
C* p = new C;
f2(*p);
delete p; // don't forget this step!
}
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 10 years ago.
Does Java really support passing by reference?
If it doesn't, why do we have the == operator for finding two objects with the same reference?
Java uses pass by value, not by reference...
But, for non primitive types the value is the value of the reference.
So == compares the values of references for Objects.
The point of distinction is between "pass**-by-reference" and "passing a** reference". You also sometimes see "call-by-..." and "pass-by-..." used interchangeably. For simplicity, I'll stick with "pass-by-...".
In academic, old-school, FORTRAN-relevant, comp-sci terminology, pass-by-reference means that the called code has access (reference) to a variable passed by the caller. Assigning to the formal parameter in the called code actually does an assignment to the caller's variable. The distinction is versus (among others) pass-by-value, which gives the called code a copy of the data (whatever it is) known to the caller.
In the contemporary Java-relevant, OO world, "having a reference" to an object means being able to get to the object itself. This is distinguished from "having a pointer" to emphasize (among other things) that one doesn't do "pointer arithmetic" on a reference. (In fact, a "reference" in this sense does not necessarily have to be an actual pointer-like memory address.)
Java passes arguments by value (in the first sense), but for object arguments, the value is a reference (in the second sense). Here's a bit of code that relies on the difference.
// called
public void munge(List<String> a0, List<String> a1) {
List<String> foo = new List<String>(); foo.add("everybody");
a0.set(0, "Goodbye");
a1 = foo;
}
// caller
...
List<String> l0 = new List<String>(); l0.add("Hello");
List<String> l1 = new List<String>(); l1.add("world");
munge(l0, l1);
...
Upon return from munge, the caller's first list, l0 will contain "Goodbye". A reference to that list was passed to munge, which called a mutating method on that referred-to object. (In other words, a0 received a copy of the value of l0, which was a reference to a string list that got modified.)
However, upon return from munge, the caller's second list, l1 still contains "world" because no methods were called on the passed object reference (the value of l1, passed by value to munge). Instead, the argument variable a1 got set to a new value (the local object reference also held in foo).
IF Java had used pass-by-reference, then upon return, l1 would have contained "everybody" because a1 would have referred to the variable l1 and not simply been initialized to a copy of its value. So the assignment to a1 would have also been an assignment to l1.
This same issue was discussed in another question, with ASCII-art to illustrate the situation.
Java does not use pass-by-reference but rather pass-by-value. Primitive value parameters are copied to the stack, as well as pointers to objects.
The == operator should be used for comparing primitive values, and for comparing object references.
Short answer is no. In Java there is only pass-by-value, and when you are working with objects (e.g. Object obj = new Object();), you are working with object references. Which get passed by value.
For details, see: Parameter passing in Java