In Java are object attributes passed by reference to other classes - java

If I have a class like such:
public class First {
int x = 1;
}
and a second class:
class Main {
public static void main(string args[]) {
First someObject = new First();
someObject.x = 2;
}
}
is only someObject.x equal to 2 or would any object of class First being created afterwards be initialized with it's x attribute being equal to 2. If not, how would one change the default value of x for any object being made of class First?

First of all, you need to read about what "pass by reference" really means. (For example, here.) Passing semantics refer to what happens to arguments in a procedure/method/subroutine/function call. In your example, there is no "passing" going on at all when you are assigning to the x field.
So your
In Java are object attributes passed by reference to other classes
is a meaningless and/or irrelevant question. (But the plain answer is that Java does not support "pass by reference". Period.)
As for what I think you are trying to ask, lets start with some facts:
The Field class declares x as an instance field.
Each instance of First has its own "copy" of the x field.
The x field is part of one and only one instance. It is not shared with any other First instance.
This is irrespective of the declared type of x ... modulo that a field whose declared type is a reference type will contain a reference to an object rather than the object itself. (But int is not a reference type.)
The new First() expression creates a new instance of the First class that is distinct from all other (past, present or future) instances of First and returns its reference.
So, in this code:
First f1 = new First();
First f2 = new First();
f1.x = 2;
System.out.println(f2.x); // prints 1.
We have two instances of First that f1 and f2 refer to (point at) distinct First instances. If you change the x field of one instance does not change the x field of the other intance. They are different fields.
However, if you had declared x as static in First, then x is no longer a distinct field for each First instance. It is now a shared by all instances of First.
As an addendum, how would one change the default value of x in the First class such that any new instance made afterwards would have a difference value of x to start?
Firstly int x = 1; in First is not defining a "default" value in the sense that Java uses that term. It is actually an initialization. (A default value is what you see if you DON'T have an initialization.)
If you wanted to implement application specific default value that is common to all instances of First and that can be changed retrospectively, you need to implement it in Java code. Maybe something like this:
public class First {
static int defaultX = 1;
private int x;
private boolean xSet = false;
public int getX() {
return xSet ? x : defaultX;
}
public void setX(int x) {
this.x = x;
this.xSet = true;
}
}
Note that in order to implement the defaulting behavior we want, we have to hide the x field (make it private) and implement the desired behavior in the getter and setter methods.

Related

Constructors: do Instance variables store separate values for objects?

Suppose we initialize the instance variables with some values, and then again initialize them inside a constructor with some other values, so does that mean that variables will hold separate values for objects regardless of what we initialized them to outside the constructor? For example:
class A {
int a = 2;
A(int p) {
a = p;
}
public void Foo(String args[]) {
A obj = new A(5);
}
}
In the above code, do 'a' and 'obj.a' hold seperate values?
In the above code, do 'a' and 'obj.a' hold seperate values?
Yes. obj.a holds the value 5, while a holds the value "there isn't any such variable and there's no meaningful answer to what its value is."
There is no a by itself, only the value of a associated with a particular instance of the class A.

Helper Methods within static method are overidding multiple variables? [duplicate]

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 5 years ago.
public class SeamCarving {
public static Seam carve_seam(int[][] disruption_matrix) {
int[][] original = disruption_matrix;
int[][] weighted_matrix = disruption_matrix;
SeamCarving s1 = new SeamCarving();
weighted_matrix = s1.buildMatrix(disruption_matrix);
....
}
In the above code I have a static method carve_seam. The method takes a matrix. That input is saved in a matrix variable called original. A calculation is performed on the matrix and that is also saved as a variable called weighted_matrix. Both are needed.
Since its in a static method, a new object of the class is made and it is called from that "s1.buildMatrix"
However, that line is doing something that is over my head. This is because afterwards, not only is weight_matrix changed (correctly from the buildMatrix method) but original is also changed to the same exact thing! How does this happen???
First thing you need to understand here is that all the three reference matrix, are referring to the same object you have passed as the input (disruption_matrix object). This is the reason why also the original and weighted_matrix are being changed.
In the first line,
int[][] original=disruption_matrix;
refers to the same object in disruption_matrix.
Then on the next line,
int[][] weighted_matrix=disruption_matrix;
refers to the same old object as well. So, you do not need to reach the line,
weighted_matrix = s1.buildMatrix(disruption_matrix);
to see that both original and weighted matrix have been changed. Actually the they have been changed when you have done the calculation to the disruption_matrix itself.
This situation is quite similar to a something like, where,
int a=10;
int b=a;
int c=a;
So, not only 'a' but also 'b' and 'c' will have their value assigned to 10.
In a OOP manner, where such same object is being assigned to different references, once a change has been made to the object through a single reference no matter that you're accessing the object through a different reference, the object has been changed.
For an example let's take this simple class,
Class A{
int val=10;
}
now, in some method we create an object and assign it to references,
A a=new A();
a.val=20;
A b=a;
b.val=30;
A c=a;
c.val=40;
As for the above code, an object is created under the reference called 'a'. In the next line, the value 'val' is accessed through that reference and has been changed from 10 to 20.
Then, the reference 'b' has been declared and it is initialized and pointed to the same object which 'a' is holding. Then in the next line, the value of that object (val) is changed again 20 to 30, but this time through 'b' instead of the reference 'a'.
Same goes to the next three lines where the value of the object is being changed from 30 to 40 through the reference 'c'.
So finally what will be the output?
System.out.println(a.val);
System.out.println(b.val);
System.out.println(c.val);
It is obviously going to give you the output,
40
40
40
This is the concept you are missing here (Pass by value and pass by reference).
In Java, Arrays are technically objects and not primitives, even for arrays of primitive types. Whenever you pass an argument to a method as an object, Java passes it as a reference; the values of the original argument change because all variables you have created are "referring" to the same object. This, however, is not the case with primitives, which are passed by value.
I suggest that whenever you need to make a matrix off of another you use the following utility method:
public static int[][] copyMatrix(int[][] original) {
int[][] copy = new int[original.length][];
for(int x = 0; x < copy.length; x++) {
copy[x] = new int[original[x].length];
for(int y = 0; y < copy[x].length; y++) {
copy[x][y] = original[x][y];
}
}
return copy;
}
At the end, your code would look like this:
public class SeamCarving {
public static Seam carve_seam(int[][] disruption_matrix) {
// no need to make an "original" variable anymore,
// since disruption_matrix already stands for it
int[][] weighted_matrix = copyMatrix(disruption_matrix);
SeamCarving s1 = new SeamCarving();
weighted_matrix = s1.buildMatrix(disruption_matrix);
....
}
}
Keep in mind that this implementation copies the arrays but not the objects. This will solve your problem when working with primitives like int but not with mutable objects.

Object value doesn't change

class smth{
public static void main(String[] args){
private Integer x = new Integer(17);
inc(x);
System.out.print("x="+x);
}
public static void inc(Integer x){
x++;
System.out.println("n="+x);
}
}
output:
n=18;
x=17;
Integer is an object and I don't understand why the value of x did not change in this case.
Cause Integer is immutable object. When you send it to method, new reference to it is created. When you do increment, reference inside method is reassigned to new Integer with value 18 but reference inside main is still referencing to old Integer with value 17.
Integer is immutable. The x++ creates a new object, and rebinds x to refer to it. The change does not propagate back to the caller since the reference to the original x was passed by value.
Any wrapper classes are immutable class.
Because x++, on an Integer object, actually means:
int temp = x.intValue();
temp++;
x = Integer.valueOf(temp);
The x variable is being assigned a new Integer instance. And since parameters are passed by value, the original reference stays unmodified.
It is because Java passes objects to methods by value and not by reference. Upon completing the method call, the object value will be the same in the calling method as it was before passing it. Within the called method, the value can change but the scope of the change is the method to which it was passed.
This is because Integer, a wrapper over the primitive int, is immutable, and Java passed object references by value. Any change made to the object reference inside the method has no effect on the object passed in: the reference is replaced with a reference to a new object, yet the original remains intact because it is immutable.
To address this issue, you need another level of indirection - you can use an array, a mutable int from apache commons, or roll your own suitably designed class.
public static void main(String argv[])
MutableInt x = new MutableInt (17);
inc(x);
System.out.print("x="+x.intValue());
}
public static void inc(MutableInt x){
x.add(1);
System.out.println("n="+x.intValue());
}
It is because the object modifying inside the method incis not the same as the one printed outside this method.
Inside the method inc x is a reference which points to an object. When you run x ++, that reassigns X to reference a new Integer object, with a different value. Thus, you are not modifying your original 'x' variable declared on the main.
You have to return the "pointer" to the new integer object:
public static int inc(Integer x){
x++;
System.out.println("n="+x);
return x;
}
public static void main(String argv[])
Integer x = new Integer(17);
x = inc(x);
System.out.print("x="+x);
}
An Integer, is a Object that contains a single int field. An
Integer is much bulkier than an int. It is sort like a Fedex box to
contain the int. Integers are immutable (source)

pass by reference/value - simple example

I know this issue has been addressed many times - but my Java/C++ knowledge is so weak I can barely understand the answers :-( ... what I'd really like is just a super simple example.
In C++ I could write the following:
void func()
{
int x = 3;
add_one(x);
// now x is 4.
}
void add_one(int &var)
{
var++;
}
What I'd like to see now is the simplest way to achieve the same effect with java.
You can't directly. The closest you can get is to put the value in an object, and pass the reference (by value, so the reference gets copied) into the method.
void func()
{
int x = 3;
int[] holder = [x];
add_one(holder);
// now holder[0] is 4. x is still 3.
}
// container here is a copy of the reference holder in the calling scope.
// both container and holder point to the same underlying array object
void add_one(int[] container)
{
container[0]++;
}
Here I use an array, but the wrapper can be any object.
In java method arguments are pass-by-value, and can't be changed in the function. You must wrap the int - or any other primitive type - in an Object or an array. Passing an Object or an array as a method argument passes a reference which can be used to modify the object.
Java already has Object based wrappers for primitive types, e.g. Integer, but these are immutable by design. Some libraries provide mutable versions of these wrappers; you can also create your own:
public class MutableInt
{
private int val;
public MutableInt(int val)
{
this.val = val;
}
public void setValue(int newVal)
{
this.val = newVal;
}
public int getValue()
{
return this.val;
}
}
void func()
{
int x = 3;
MutableInt wrapper = new MutableInt(x);
add_one(wrapper);
}
void add_one(MutableInt arg)
{
arg.setValue(arg.getValue() + 1);
}
You cannot do this. Java is only pass by value. Primitives are obvious, but the thing that's passed for objects is a reference, not the object itself.
As you can see from the other answers, Java is purely pass by value. Objects are passed by what some call "value-reference". Since an object in java is simply a pointer reference, you can think of the "value" as the address where the object lives on the heap. So when you make a method call, you're copying the "value", aka address, to the method parameter:
Object x = new Object();
foo(x);
During object creation
Heap --> allocate Object (5000)
Variable Declaration
Stack --> allocate local variable (1000)
Variable Assignment
Stack address 1000 set to 5000 (to point to object instance)
So you can see that there are two separate memory allocations here. The "value" of the variable is considered to be it's address on the heap.
Method Call
Stack --> allocate method parameter 8000
Stack address 8000 set to same value as passed parameter 5000
This is why if you reassign an object instance in a method, it does not propagate back to the caller. You would have changed the heap location at stack location 8000. And the calling method's stack location 1000 still has the value 5000 (the original object instance).
Think of it like this in C:
void method(myobject * obj);
You can certainly change fields of "obj", and you can do this locally:
obj = new myobject();
But the caller will still see the original value it passed.
Java has no analog to the & reference operator.
And there are built in classes which can be used for the your purposes. AtomicInteger, AtomicLong, etc... are mutable, though you may suffer a performance hit due to synchronization involved.
I would recommend a generic ValueHolder class to account for all situations where you want to simulate pass by reference:
public class ValueHolder<T> {
private T value;
// getter/setter/constructor
}
Java allows copy by reference for objects and copy by vlaue for primitive types (int,float,etc..). This is so by default and is not subject to change. If you need to change the value of an int inside a function, then you can use the class Integer for example
public int getOneMore(int val) {
return val + 1;
}

Can someone explain to me in detail the use of 'this'?

I don't really understand the use of 'this' in Java. If someone could help me clarify I would really appreciate it.
On this website it says: http://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
"Within an instance method or a constructor, this is a reference to the current object — the object whose method or constructor is being called. You can refer to any member of the current object from within an instance method or a constructor by using this."
and it gives the following example:
For example, the Point class was written like this
public class Point {
public int x = 0;
public int y = 0;
//constructor
public Point(int a, int b) {
x = a;
y = b;
}
}
but it could have been written like this:
public class Point {
public int x = 0;
public int y = 0;
//constructor
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
Yet, I still don't fully understand why x = a could have been written as this.x = x? Why isn't it this.x = a? Why is the x on the left side?
I'm sorry but I am very new to Java. I apologize for boring the experts.
If some variable/argument with same name as object's property is defined, it "overlaps" the name of that property and one should use this.var_name.
So yes, it could be written as this.x = a, but is somewhat redundant.
In the second example one of the arguments is named x. By referencing this.x, you mean the x field/property of the class the method is part of. It could read as:
Point.x = argument x
this is being used to differentiate the two, making the meaning of the code clear.
It isn't this.x = a because there isn't an 'a' in the second example. The point is that you can reuse the same variable name, which is less confusing :-|
The idea is to make it very clear that you are providing values for x and yin your constructor.
Problem is now that due to the scoping rules that within the constructor x refers to the passed value and not the field x. Hence x = x results in the parameter being assigned its own value and the shadowed field untouched. This is usually not what is wanted.
Hence, a mechanism is needed to say "I need another x than the one immediately visible here". Here this refers to the current object - so this.x refers to a field in the current object, and super refers to the object this object extends so you can get to a field "up higher".
this is a reference to the current object, so you access it like any other object - this.x is the x property of this. So x is the argument passed in, which you assign to this.x.
This is namespacing - the idea that a name for a variable only applies within a given block of code. In java, where you are working within a function belonging to the class, you are inside the namespace for that class, however, if you have another variable with the same name as an argument, it will take precedence, and you instead access the attribute via this.
this can also be used in other ways. For example, say I want to draw the current object to the screen in a fictional library, from within the class, I could do:
window.draw(this)
You can also call functions
this allows us to reference the object we are currently 'inside', so we can pass the current object as an argument. This is very useful. (No pun intended).
"this" is a reference to the current object you are using. You use it when you have a name clash between a field and a parameter. Parameter takes precedence over fields.
No clash, no need for this:
public Point(int a, int b) {
x = a;
y = b;
}
But this will work, too:
public Point(int a, int b) {
this.x = a;
this.y = b;
}
Name clash, need to use "this":
public Point(int x, int y) {
this.x = x;
this.y = y;
}
If you did only
public Point(int x, int y) {
x = x;
y = y;
}
then you would just assign parameters with its own value, which effectively does nothing.
There are more usages of keyword "this".
"This" is a hidden "argument" that gets passed for you so that the methods that operate on the object know which object exactly they are to operate on.
Now imagine you pass the argument of name "x" but the class does have that var name defined already. What happens ? Well, the name x that "belongs" to the object and the argument x are not the same data-object yet they share the name.
In order to disambiguate, you need to say explicitly "this.x", which tells the compiler that you're talking about the x that already belongs to "this" object. (That is, the current object you're trying to operate on.)
In the second example, the arguments to the constructor are not a and b; they were changed to x and y, and this.x = x; means "assign this Point class instance's member variable x the value passed to the constructor as x".
This really has to do with how the java compiler identifies variables by their name. Function (formaal) parameters names precede class member variables. In the first example the formal parameter names are a and b and they do not collide with the member variables x and y so writing
x = a;
is logical as x can only mean the member variable class Point.
In the second example x refers both to the formal parameter name and to the member variable. Writing x within the function body refers to the parameter so if you need some other way in order to refer to the member variable x. This is done by explicitly accessing a member via the 'this' keyword.

Categories

Resources