I'm trying to do some practice for an exam and need some help (did I do them correctly? If not, why?) on these problems about java primitives and java objects. These are all true or false.
The following variable declaration is a reference to an object which is dynamically allocated and stored in the heap: int x = 7;
False, because it is pass by value since int is primitive
The following variable declaration is a reference to an object which is dynamically allocated and stored in the heap: Integer x = 7;
True, because it is referencing an object stored on the heap
If you pass the variable ‘x’ as declared in (1) to a method, that variable is passed by reference, and its value may be modified by the called function.
False,because Java only does pass by value
If you pass the variable ‘x’ as declared in (2) to a method, a copy of that
variable is created in the heap, and passed to the function, so that the function’s object
reference is pointing to a distinct place in memory.
True, because variable is in the stack but it is pointing to a place in the heap
Thank you all for the help.
(4) is false for two reasons:
"a copy of that variable is created in the heap" is false. Only objects are on the heap. The local variable in a function is not on the heap. The value of that variable is simply passed, i.e. copied into the stack frame of the called function.
"the function’s object reference is pointing to a distinct place in memory." is false. The function's reference will point to the same place in memory. That's the point of passing -- the value of the variable inside the function is the same as the value that was passed. The value of a reference is where it points.
4) If you pass the variable ‘x’ as declared in (2) to a method, a copy
of that variable is created in the heap, and passed to the function,
so that the function’s object reference is pointing to a distinct
place in memory.
Okay, this can be a little sketchy. If dealing with objects, you are not creating a copy of the object and passing the copy to the method. You are creating a copy of the reference to the object, and passing that over by value.
Actually there is a reason 2 is wrong - but its probably not the reason the person who set it expects.
Integer x = 7;
Will get turned into:
Integer x = Integer.valueOf(7);
Which will re-use a cached value for all integers in the range -128 to +127 inclusive. (It may reuse them for other values too).
So you will get a reference to an object which is present in the JVM implementation dependant cached storage for common Integer values.
False because Integer is an object. So you will be passing just the reference to the object address in the function. It is standard in Java.
Related
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.
In Java, when we assign an object to a variable of the matching class type, the variable only contains a reference to the memory location where the object in stored.
Is the case same with Primitive data types as well?
I mean, in int i = 10;, does i store the address of the memory location where the value 10 is stored?
PS: In sharp contrast, C++ actually stores the objects and not the references, right? Unless we use pointers and reference variables, right?
In Java, everything is stored by value. The value of an Object type in contrast to a primitive is the reference. Note that the wrapper types (like Integer) do constant interning for low values.
Indeed, in Java, primitives are always handled by value and objects are always handled by reference. Note however that these are the semantics; i.e., what the meaning of Java code is supposed to be. A particular implementation of Java (i.e., a JVM) is free to manage memory however it likes internally, as long as it appears to obey the correct semantics for anything that can be observed (i.e., output of the program).
And your PS remark is also correct.
I'm curious to know how Integer and Integer Array are stored on the stack/heap in java, is there a link someone could point me to? Or could someone explain it to me please.
Update 1:
and how does this affect the way an integer and an integer array are passed as arguments to methods in Java.
Thank You
Whenever you declare a variable within a local scope(a method) it gets put on the stack.
That is: Type myVariable will push space for a new variable onto that methods stack frame, but it's not usable yet as it's uninitialized.
When you assign a value to the variable, that value is put into the reserved space on the stack.
Now here's the tricky part. If the type is primitive, the value contains the value you assigned. For example, int a = 55 will literally put the value 55 into that space.
However, if the type is non primitive, that is some subclass of Object, then the value put onto the stack is actually a memory address. This memory address points to a place on the heap, which is where the actual Object is stored.
The object is put into the heap on creation.
An Example
private void myMethod()
{
Object myObject = new Object();
}
We're declaring a variable, so we get space on the stack frame. The type is an Object, so this value is going to be a pointer to the space on the heap that was allocated when the Object was created.
Variables contains only references to this objects and this references stored in stack in case of local variables, but data of objects the point to stored in heap.
You can read more, for example, here: link
method variables are stored in Stack. Objects , in the other hand are stored in the Heap as the image below demonstrates it.
That's why if you get StackOverFlowException, that means you have declared too many variables in a method or you are calling too many methods in a recursive call. And if you get Java Heap Space Error, that means you are creating more objects than you do.
For Stack and Heap explanation, I recommend this link
Following declaration
void insert_LL(Node *head, int data);
when called, a copy of head pointer reaches the function, so if a node is added at the head, the value of the head is changed. But, as we have the local copy of head so the actual head pointer isn't changed. So we declare it as follows
void insert_LL(Node **head, int data);
My question:
Is the above explanation correct?
If yes, so that means in C, it is always a pass by value (a copy of pointer is reached in the function) which is same as in Java. Am I correct?
If yes, so how does pass by reference/pointer come into the picture?
1- YES
2- YES
3- In C, Pass-by-reference is simulated by passing the address of a variable (a pointer) and dereferencing that address within the function to read or write the actual variable. This is referred as "C style pass-by-reference.".
Pass by reference is not the term to be used in C. The address value of the pointer variable is passed. The compiler stores references to the variables with the names given to the memory locations where the variable is held.
The major difference between a reference and a pointer is that "pointer" can take any address value unless made "const". Whereas when you pass by reference, you can't.
What are the differences between a pointer variable and a reference variable in C++?
This thread will do all the needful.
So I have an algorithm that forces me to pass in an object as a parameter recursively and on different depths of the recursion it sets the values of the object. The problem is Java isn't allowing me to do this because they pass in by value or something else that is just messing me up. How can you make sure that the object passed in retains the value set?
You never pass an object as an argument in Java. You either pass a reference or a primitive value. The argument is always passed by value. Java doesn't have pass-by-reference at all.
If you're passing in a reference to an object, and you want to make sure the code you call doesn't change the data within that object, your options are:
Create a copy and pass in a reference to that instead
Make your type immutable in the first place.
EDIT: Just to make it clear, if you have:
Foo f = new Foo();
then the value of f is not a Foo object. It's a reference to a Foo object. If you now call:
doSomething(f);
then the value of f is copied as the original value of the parameter within doSomething. That behaviour is basically the definition of pass-by-value. There's nothing doSomething can to do change the value of f - it will still refer to the same object afterwards. The data within that object may have changed, but it won't be a different object.
In a real-world analogy: if I give you a copy of my address, you can go and paint the front door, but you can't change where I live.
As Jon states, all non-primitives are passed by passing a copy of the reference. You don't have a choice. So your recursive method should be able to update the object if it is mutable. HOWEVER, you can't reassign a reference and expect it to propagate back up the call stack. And remember that Strings are not mutable.
In other words, if you do the following, you have not changed the object that was passed:
void myMethod(Object o){
o = new Object();
}
The above changes the local reference to o but does not change the caller's reference to o. If you need to do something like this you would need to return o.