Can objects be passed by value rather than by reference in Java? - java

Let's consider the following code in Java.
package obj;
final class First
{
public int x;
public First(int x)
{
this.x=x;
}
}
final class Second
{
public Second(First o)
{
o.x=10;
}
}
final public class Main
{
public static void main(String[] args)
{
First f=new First(50);
Second s=new Second(f);
System.out.println("x = "+f.x);
}
}
In the above code, we are supplying a value 50 through the statement First f=new First(50); which is being assigned to a class member x of type int in the constructor body in the class First.
In the class Second, the object f of the class First is being passed through the statement Second s=new Second(f); and we are modifying the value of the instance variable x held in that object to 10 which will affect the original object f because in Java objects are always passed by reference and not by value.
In some specific situations, it may be crucial not to allow such changes to the original objects. Is there any mechanism in Java that may allow us to prevent such modifications? (that might allow us to pass objects by value)

No, the object isn't being passed at all in Second. The reference is being passed by value.
Java always uses pass-by-value, but the value of any expression is only ever a primitive type or a reference - never an object.
It sounds like you want to create a copy of an existing object, then pass a reference to that new object to the method (by value). Quite what constitutes a "copy" will depend on the data in the class. (You may be able to get away with a shallow copy, or you may need to go deeper etc.)

No, there aren't. I would say that your example is not a very good one: if you want to ensure that something doesn't change, don't provide ways to change it. Causing the change to be lost afterwards is misleading at best.

First f=new First(50);
Second s=new Second(f);
in first line you are create a reference variable of Object type First and in 2nd line it is pass to Class Second
So as Jon Skeet say in java "Java always uses pass-by-value, but the value of any expression is only ever a primitive type or a reference - never an object."
And if if u don't want to change the value of property then u must be pass new object of class First
Because if u have a reference of any class then u can change the property of that class ..
Or u can create a copy of that object which is at the end creating a new object of First Class

Related

In java, is an object considered a variable?

One source I am studying defines an array as "a collection of variables under one name, where the variables are accessed by index numbers."
But then I realized that you can have an array of objects (or an array of pointers to objects, at least).
This got me to wonder what a variable is defined as in java, as I did not consider an object to be a variable. Jenkov Tutorials cites a variable as being "a piece of memory that can contain a data value."
And since I believe an object fits this definition, is an object considered a variable?
Calling an array a "collection of variables" is arguably stretching the definition already. But an array is certainly a collection of references that can be made to point to different objects in memory, and each such reference can reasonably be called a variable.
Asking "is an object a variable" is a little weird in the first place. In Object o = new Object(), o is clearly a variable, though remember it's a reference to an object in the heap, not the object itself.
Honestly, "variable" is a pretty flexible, ill-defined term -- is a field a variable? The return result of a method? It depends on who's talking and what fuzzy definition they're using today.
is an object considered a variable?
No, these are two distinct things.
The first one (the object) is the value and the second one (the variable) is a way to reference an object, generally to use it (invoking a series of method on it for example).
For example when you write :
new Dog()
You instantiate a Dog. Nice. But suppose you want feed it if it is hungry.
You cannot if you have not a way to chain a series of method on this object.
By storing the reference of the Dog in a dog variable you can do it :
Dog dog = new Dog();
if (dog.isHungry()){
dog.feed();
}
Jenkov Tutorials cites a variable as being "a piece of memory that
can contain a data value."
It says the same thing.
But this :
One source I am studying defines an array as "a collection of
variables under one name, where the variables are accessed by index
numbers."
is rather misleading.
An array is an object that has a state that contains, among other things, elements of the array.
The way which the elements are referenced in is a implementation detail of the Array class and I would not affirm that each element is stored in a specific variable.
An object is created when you call the constructor with the reserved word new.
For example:
Object a = new Object();
a will be the variable of that new object created and will go to reserved memory for that object. You are instantiating that new variable and that variable is associated with that object.
Hope might this will help you to understand it better...
class Bulb
{
private int w;
public void setWattage(int e)
{
w=e;
}
public int getWattage()
{
return w;
}
}
class Test
{
public static void main(String args[])
{
Bulb b[];
b=new Bulb[2];
b[0]=new Bulb();
b[1]=new Bulb();
b[0].setWattage(60);
b[1].setWattage(100);
System.out.println(b[0].getWattage());
}
}
here b[0] and b[1] are reference variables who have the address of two Bulb objects

Java object creation difference

I'm new to OOP concepts in Java. What is the difference between these two incidents?
1.
ClassName obj_name = new ClassName();
obj_name.method();
2.
new ClassName().method();
A good explanation is much appreciated. Thanks
In Option(1), you are still having/holding the reference to the object, so you can reuse that reference to access/call the other members(method/variables) of the object (class).
In Option (2), you don't have the reference (i.e., reference has been lost), so you will NOT be able to use it again.
One point to remember is that if you want to access the same object members multiple times, you need to hold the reference (use option 1 above), rather than creating the object (option 2) again and again (which is costly operation i.e., occupies memory).
Please refer the below link for more details:
https://docs.oracle.com/javase/tutorial/java/javaOO/usingobject.html
The reference variable obj_name hold the object of ClassName.through which you can call the instance method of ClassName through reference variable obj_name.
Whene ever we create an object and dont assign its reference to any reference variable its Known as Anonymous object instantiation.The Advantage of this type of instantiation is that you can only do the limited operation on that.Like you can call a single method.
If you want to perform mopre operation then reference varaibale which hold the object is better approach.If you have multiple method in your class and you want to use them then option 1 is right choice.
for details please go through this Link
While they might accomplish the same objective for the first call, the two approaches do fundamentally different things in terms of class definition and instantiation.
ClassName object = new ClassName();`
object.method();`
This is a case of instantiation. You create a new ClassName object which possesses certain instance fields and methods. It can call these methods, and the result may cause its instance fields to change.
ClassName.method();
On the other hand, this approach does not create an instance of the class. Instead, it calls method as a class attribute. Thus, the result can change fields in ClassName, but it won't necessarily existing fields in already-instantiated objects.
public class ClassName(){
public int attr = 0;
public ClassName(){}
public void setAttr(int value){
this.attr = value;
}
public void method(int value){
this.attr += value;
}
}
Now, using the first approach, we can create a newObj and call newObj.method(100). This will increase newObj's instance variable attr by 100.
To see the difference between the two approaches, let's use setAttr(200) to change the object's attr to 200.
Next, if we just use ClassName.method(100), the class's attr value will become 100 for all future instances of ClassName. So if we create ClassName nextObj = new ClassName(), this new instance of ClassName will have attr of 100, while newObj will still have attr of 200.
Hopefully this explains the core difference between the two approaches.
in option 1 you are creating an object with new keyword
followed by constructor and that object is referenced by class_name
obj_name variable so obj_name is pointing to that object.
In option 2 you not referencing to that object. just you make an
object and call the method with no references so that object is
eligible for garbage collection.

How do I create an object within method sending reference as a parameter [duplicate]

I'm a complete Java noob. I know that Java treats all parameters as pass by value and there are several other threads where people explain this.
For example, in C++ I can do:
void makeAThree(int &n)
{
n = 3;
}
int main()
{
int myInt = 4;
makeAThree(myInt);
cout << myInt;
}
Which will output 3. I know that in Java, all parameters are passed by value and thus you can not manipulate the parameter passed in. Is there a standard way to simulate pass by reference in Java? Is there no way to call a function that manipulates a variable passed in? It's tough for me to wrap my head around the idea of there being no way to do this.
The primary way you can simulate passing a reference is to pass a container that holds the value.
static void makeAThree(Reference<Integer> ref)
{
ref.set(3);
}
public static void main(String[] args)
{
Reference<Integer> myInt = new Reference<>(4);
makeAThree(myInt);
System.out.println(myInt.get());
}
Since in Java, it is references to objects that are passed by value (the object itself is never passed at all), setting ref to 3 in makeAThree changes the same object referred to by myInt in main().
Disclaimer: Reference isn't a class you can just use with out-of-the-box Java. I'm using it here as a placeholder for any other object type. Here's a very simple implementation:
public class Reference<T> {
private T referent;
public Reference(T initialValue) {
referent = initialValue;
}
public void set(T newVal) {
referent = newVal;
}
public T get() {
return referent;
}
}
Edit
That's not to say it's great practice to modify the arguments to your method. Often this would be considered a side-effect. Usually it is best practice to limit the outputs of your method to the return value and this (if the method is an instance method). Modifying an argument is a very "C" way of designing a method and doesn't map well to object-oriented programming.
You can use an array of size 1
Java pass everything by value, if it's an object then what would be passed is the reference value of the object. It's like,
void someMethod()
{
int value = 4;
changeInt(value);
System.out.printlin(value);
}
public void changeInt(int x)
{
x = x + 1;
}
above code will print 4, because it's passed by value
class SomeClass
{
int x;
}
void someMethod()
{
SomeClass value = new SomeClass();
value.x = 4;
changeCls(value);
System.out.printlin(value.x);
}
public void changeCls(SomeClass cls)
{
cls = new SomeClass();
cls.x = 5;
}
Above code will still print 4, because the object is passed by value and the reference to the object is passed here, even it's changed inside the method it won't reflect to the method 'someMethod'.
class SomeClass
{
int x;
}
void someMethod()
{
SomeClass value = new SomeClass();
value.x = 4;
changeCls(value);
System.out.printlin(value.x);
}
public void changeCls(SomeClass cls)
{
cls.x = cls.x + 1;
}
here also it passes the object by value, and this value will be the reference to the object. So when you change some field of this object it will reflect to the all the places where the object is referred. Hence it would print 5. So this can be the way you can use to do what you want. Encapsulate the value in an object and pass it to the method where you want to change it.
Java is pass-by-value that mean pass-by-copy. We cannot do arithmetic on a reference variable as in C++. In-short Java is not C/C++.
So as a workaround you can do this:
public static void main (String [] args) {
int myInt = 4;
myInt = makeAThree(myInt);
}
static int makeAThree(int n)
{
return n = 3;
}
P.S. Just made the method static so as to use it without class object. No other intention. ;)
I ran some of the various scenarios above.
Yes, if you wanted to change a value outside of the function without returning the same primitive, you'd have to pass it a single unit array of that primitive. HOWEVER, in Java, Array's are all internal objects. You please note that if you pass 'value' by name to the println() there is no compile error and it prints hashes because of the toString() native to the internal array class. You will note that those names change as they print (put it in a long loop and watch). Sadly, Java hasn't gotten the idea that we WOULD like a protected yet physically static address space available to us for certain reasons. It would hurt Java's security mechanisms though. The fact that we can't depend on known addresses means that it's harder to hack at that. Java performance is fantastic because we have fast processors. If you need faster or smaller, that's for other languages. I remember this from way back when in 1999 reading an article in Dobbs just about this argument. Since it's a web aware language meant to function online, this was a big design concession to security. Your PC in 1999 had 64mb to 256mb of RAM and ran around 800mhz
Today, your mobile device has 2 to 8 times that ram and is 200-700mhz faster and does WAY more ops per tick, and Java is the preferred language for Android, the dominant OS by unit sales (iOS still rocks, i gotta learn Objective C someday i guess, hate the syntax i've seen though).
If you passed int[] instead of int to this code you get 5 back from someMethod() calling it.
public void changeInt(int x)
{
x = x + 1;
}
public void changeInt(int[] x)
{
x[0] += 1;
}
This is a confusing selection from above. The code WOULD work if the author hadn't hidden the passed variable by declaring a local variable of the same name. OFCOURSE this isn't going to work, ignore the following example cited from above for clarity.
public void changeCls(SomeClass cls)
{
cls = new SomeClass();
cls.x = 5;
}
Above code will still print 4, because the passed object is HIDDEN FROM SCOPE by the local declaration. Also, this is inside a method, so I think even calling this and super wouldn't clarify it properly.
If it weren't hidden locally in the method, then it would have changed the value of the object passed externally.
To accomplish the changing of a primitive variable in a method there are 2 basic options :
1) If you want to change values on a primitive in a different method you can wrap the primitive in a "java bean" object, which will be essentially like a pointer.
Or
2) You can use an AtomicInteger/AtomicLong class which are used to concurrency, when many threads might need to modify a variable....so the variables has to have state that is consistent. Theses classes wrap primitives for you.
Warning : you are usually better off returning the new value, rather than setting/editting it internally in a method, from a maintainability standpoint ..
One quick way to achieving simulate passing by reference is to move the arguments to member variables of the enclosing class.
Although there are multiple ways to do it such as using a class or array wrapper or moving them to the function return type, the code may not turn out clean. If you are like me, the reason to ask such a question is that a piece of Java code has already been coded in a C++ way (which does not work) and a quick fix is needed. For example, in a recursion program such as depth-first-search, we may need to keep multiple variables in the C++ recursion function's argument list such as search path, flags whether the search should end. If you are in such a situation, the quickest fix is to make these argument variables into class member variables. Take care of the variable life cycle though and reset their values when necessary.
Java uses pass by value for everything.
As far as I understand you are not really sure if you can modify a variable passed in.
When you pass an object to a method, and if you use that object within that method, you are actually modifying that object. However you are modifying that object on a copy of it which still points to the same object. So actually when you pass an object to a method, you can modify it.
Once again, everything in java is pass by value.period.

How to make a reference between two integers in java? [duplicate]

In a class, I have:
private Foo bar;
public Constructor(Foo bar)
{
this.bar = bar;
}
Instead of creating a copy of bar from the object provided in the parameter, is it possible to include a pointer to bar in the constructor such that changing the original bar changes the field in this object?
Another way of putting it:
int x = 7;
int y = x;
x = 9;
System.out.print(y); //Prints 7.
It is possible to set it up so that printing y prints 9 instead of 7?
When a variable is used as argument to a method, it's content is always copied. (Java has only call-by-value.) What's important to understand here, is that you can only refer to objects through references. So what actually happens when you pass a variable referring to an object, is that you pass the reference to the object (by value!).
Someone may tell you "primitives are passed by value" and "non primitives are passed by reference", but that is merely because a variable can never contain an object to begin with, only a reference to an object. When this someone understands this, he will agree that even variables referring to objects are passed by value.
From Is Java "pass-by-reference" or "pass-by-value"?
Java is always pass-by-value. The difficult thing can be to understand that Java passes objects as references passed by value.
From http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
Java does manipulate objects by reference, and all object variables are references. However, Java doesn't pass method arguments by reference; it passes them by value.
In Java, there is no counter part to the C++ "reference type" for primitives.
Your last example works that way because int is a primitive, it is copied by value. In the first example, "this.bar" would hold a copy of the reference (sort of pointer) to bar. So if you change the original bar (internally), the change will be reflected in your class. Try it.
To get that behavior you could modify a member of an object:
public class Number{
int value;
Number(int value){
this.value = value;
}
public String toString() {
return "" + value;
}
}
You could then do:
Number x = new Number(7);
Number y = x;
x.value = 9;
System.out.println(y);//prints 9
Java never copies objects. It's easiest to think of in terms of for each "new" you will have one object instance--never more.
People get REALLY CONFUSING when they discuss this in terms of pass by reference/pass by value, if you aren't amazingly familiar with what these terms mean, I suggest you ignore them and just remember that Java never copies objects.
So java works exactly the way you wanted your first example to work, and this is a core part of OO Design--the fact that once you've instantiated an object, it's the same object for everyone using it.
Dealing with primitives and references is a little different--since they aren't objects they are always copied--but the net effect is that java is just about always doing what you want it to do without extra syntax or confusing options.
In order to keep the original value of member bar, you will need to implement Cloneable interface. Then before assigning a new value to the object, you will need to make a clone of it and pass the cloned value and assign new values to the cloned object. Here is a tutorial on how to do it http://www.java-tips.org/java-se-tips/java.lang/how-to-implement-cloneable-interface.html .

Function didn't change the value - JAVA 6 SE

I can't understand why the overloaded function 'increase' does not change Integer but does change Point.
The propuse of 'Integer' class is to wrap int so it will be a reference Type.
import java.awt.Point;
public class test2 {
public static void main(String[] args) {
///1
Integer i = new Integer(0);
increase(i);
System.out.println(i);
///2
Point p = new Point(0,0);
increase(p);
System.out.println(p);
}
public static void increase(Integer i){
i = 1;
}
public static void increase(Point p){
p.setLocation(1, 1);
}
}
the output is :
0
java.awt.Point[x=1,y=1]
Also, is their a simple way to pass a variable to a function by reference in Java?
Integer class is an immutable class, that means its content can't be changed after it's created.
Also, Java is pass-by-value so the variable i is passed by value, and the fact that it changes inside the function has no effect on the caller.
Read here: http://en.wikipedia.org/wiki/Immutable_object for more information on immutable objects.
The simple answer is that Java uses pass by value, not pass by reference.
In the Point case, the method is changing a field of the point object whose reference was passed into the method.
In the Integer case, the method is simply assigning a new value to the local variable i. This does not update the variable i in the calling method, because Java uses pass by reference.
The other issue is that Integer has no setValue methods because it is immutable. If you want to do the equivalent of what the Point version of the method is doing, you will have to define an IntegerHolder class that has both a getter and a setter, together with methods such as increase, that your application needs. (Alternatively, find such a class in a 3rd party library.)
Integer objects are immutable, i.e. you can't change them. If you could, the syntax would be like
i.setValue(1);
If you want to pass a non-object by reference, you can either wrap it in an array of length 1 or (better) create a trivial wrapper. However, there is little reason to do so - don't port your code from C 1:1. Usually, you should have a semantically loaded object, like an Account on which you can call the increase and decrease (or maybe just setBalance) methods.
In this function:
public static void increase(Integer i){
i = 1;
}
autoboxing makes this equivalent to:
public static void increase(Integer i){
i = new Integer(1);
}
i.e. it changes the reference that i contains, not the value that it contains. The Integer object is itself immutable, there's actually no way to change the value of one after it has been created.
Since that reference is a local variable, any changes to it will not affect the variable that was passed in.
When you write i = 1, you are changing the i parameter to point to a new boxed Integer instance.
The original Integer instance that you passed to the function is not—and cannot be—changed—Integers are immutable
Answer here: http://www.javaworld.com/javaworld/javaqa/2000-06/01-qa-0602-immutable.html
This reference could be useful: http://javadude.com/articles/passbyvalue.htm
If you wanted the two methods to be equivalent, the second one would look like this:
public static void increase(Point p){
p = new Point(1, 1);
}
And then you would see that it outputs the original point here, too.
There is no pass a variable to a function by reference in Java.
You can simulate it by passing an object which contains the variable (like you did in your increase(Point) method) - you'll have to be sure to assign to the variable, though, not to the object containing the variable.
As said before, there are several "mutable wrappers" around (for example org.omg.CORBA.IntHolder and java.util.concurrent.AtomicInteger in the standard API), but it is not difficult to create your own, and in most cases it would be better to use a sensible "Business object" like an "Account" instead.

Categories

Resources