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.
Related
Should I use a normal method that needs an object to call it or a static function method for an increment in the value of a data member of an object. Such as
public void incSize() {
this.size++;
}
or such as
public static void incSize(Number num1) {
num1.size++;
}
For something like this, where the logic and purpose of the function is intrinsically bound to a single object, use a member function instead of a static one. It means that all the operations you can perform on an object are grouped logically by the object you perform the operation on, which is easier to use.
In my opinion, and likely the opinions of many others, it's much easier to see what's going on with:
foo.incSize();
Compared to:
Foo.incSize(foo);
Static functions are good for describing computation that's relevant to a class, but not necessarily dependent on having an object of that class. For example, Integer.parseInt is static because the functionality of parsing to an integer is relevant to the integer class, but is still usable when you don't have an object of that class. Again, compare:
int x = Integer.parseInt("0");
To:
Integer x;
x.parseInt("0");
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.
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 .
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
How can I pass a primitive type by reference in java? For instance, how do I make an int passed to a method modifiable?
There isn't a way to pass a primitive directly by reference in Java.
A workaround is to instead pass a reference to an instance of a wrapper class, which then contains the primitive as a member field. Such a wrapper class could be extremely simple to write for yourself:
public class IntRef { public int value; }
But how about some pre-built wrapper classes, so we don't have to write our own? OK:
The Apache commons-lang Mutable* classes:
Advantages: Good performance for single threaded use. Completeness.
Disadvantages: Introduces a third-party library dependency. No built-in concurrency controls.
Representative classes: MutableBoolean, MutableByte, MutableDouble, MutableFloat, MutableInt, MutableLong, MutableObject, MutableShort.
The java.util.concurrent.atomic Atomic* classes:
Advantages: Part of the standard Java (1.5+) API. Built-in concurrency controls.
Disadvantages: Small performance hit when used in a single-threaded setting. Missing direct support for some datatypes, e.g. there is no AtomicShort.
Representative classes: AtomicBoolean, AtomicInteger, AtomicLong, and AtomicReference.
Note: As user ColinD shows in his answer, AtomicReference can be used to approximate some of the missing classes, e.g. AtomicShort.
Length 1 primitive array
OscarRyz's answer demonstrates using a length 1 array to "wrap" a primitive value.
Advantages: Quick to write. Performant. No 3rd party library necessary.
Disadvantages: A little dirty. No built-in concurrency controls. Results in code that does not (clearly) self-document: is the array in the method signature there so I can pass multiple values? Or is it here as scaffolding for pass-by-reference emulation?
Also see
The answers to StackOverflow question "Mutable boolean field in Java".
My Opinion
In Java, you should strive to use the above approaches sparingly or not at all. In C it is common to use a function's return value to relay a status code (SUCCESS/FAILURE), while a function's actual output is relayed via one or more out-parameters. In Java, it is best to use Exceptions instead of return codes. This frees up method return values to be used for carrying the actual method output -- a design pattern which most Java programmers find to be more natural than out-parameters.
Nothing in java is passed by reference. It's all passed by value.
Edit: Both primitives and object types are passed by value. You can never alter the passed value/reference and expect the originating value/reference to change. Example:
String a;
int b;
doSomething(a, b);
...
public void doSomething(String myA, int myB) {
// whatever I do to "myA" and "myB" here will never ever ever change
// the "a" and "b"
}
The only way to get around this hurdle, regardless of it being a primitive or reference, is to pass a container object, or use the return value.
With a holder:
private class MyStringHolder {
String a;
MyStringHolder(String a) {
this.a = a;
}
}
MyStringHolder holdA = new MyStringHolder("something");
public void doSomething(MyStringHolder holder) {
// alter holder.a here and it changes.
}
With return value
int b = 42;
b = doSomething(b);
public int doSomething(int b) {
return b + 1;
}
Pass an AtomicInteger, AtomicBoolean, etc. instead. There isn't one for every primitive type, but you can use, say, an AtomicReference<Short> if necessary too.
Do note: there should very rarely be a need to do something like this in Java. When you want to do it, I'd recommend rethinking what you're trying to do and seeing if you can't do it some other way (using a method that returns an int, say... what exactly the best thing to do is will vary from situation to situation).
That's not possible in Java, as an alternative you can wrap it in a single element array.
void demo() {
int [] a = { 0 };
increment ( a )
}
void increment( int [] v ) {
v[0]++;
}
But there are always better options.
You can't. But you can return an integer which is a modified value
int i = 0;
i = doSomething(i);
If you are passing in more than one you may wish to create a Data Transfer Object (a class specifically to contain a set of variables which can be passed to classes).
Pass an object that has that value as a field.
That's not possible in Java
One option is to use classes like java.lang.Integer, then you're not passing a primitive at all.
On the other hand, you can just use code like:
int a = 5;
a = func(a);
and have func return the modified value.