This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is Java pass by reference?
So consider the following two examples and their respective output:
public class LooksLikePassByValue {
public static void main(String[] args) {
Integer num = 1;
change(num);
System.out.println(num);
}
public static void change(Integer num)
{
num = 2;
}
}
Output:
1
public class LooksLikePassByReference {
public static void main(String[] args) {
Properties properties = new Properties();
properties.setProperty("url", "www.google.com");
change(properties);
System.out.println(properties.getProperty("url"));
}
public static void change(Properties properties2)
{
properties2.setProperty("url", "www.yahoo.com");
}
}
Output:
www.yahoo.com
Why would this be www.yahoo.com? This doesn't look like passbyvalue to me.
The reference is passed by value. But the new reference is still pointing to the same original object. So you modify it. In your first example with the Integer you are changing the object to which the reference points. So the original one is not modified.
Your first example does:
num = 2
That is the same as
num = new Integer(2)
So you see how it is not quite the same as your second example. If Integer let you set the value in it, you could have done:
num.setValue(2) // I know Integer doesn't allow this, but imagine it did.
which would have done exactly what the second example did.
This is pass-by-value, but the value is the reference to properties, and you don't change it, only some inner field of it.
In the first case you change the reference, not any member of the reference, while in the second you change a member of the reference, but leave the reference as is.
Try this:
public class LooksLikePassByReference {
public static void main(String[] args) {
Properties properties = new Properties();
properties.setProperty("url", "www.google.com");
change(properties);
System.out.println(properties.getProperty("url"));
}
public static void change(Properties properties2)
{
properties2 = new Properties();
properties2.setProperty("url", "www.yahoo.com");
}
}
It prints out "www.google.com".
You are actually passing the value of the reference, so changes made to the object via that reference will be seen. If you assign a new object reference to the parameter, though, that change will not be reflected, since you've only passed the value of the reference, rather than an actual reference to a variable.
That's because properties2 is nothing more than an object reference. This means the references passed to the method are actually copies of the original references. As this illustrates,
Related
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 2 years ago.
Please see my code below. I have a functional interface IFace with a method. I'm creating an implementation using Method reference from a class instance of Test. Can anyone tell me how the interface still refers to the instance method even if the reference is nullified? or reference is changed...?
public class Test {
private int intVar;
public Test() {
intVar = 123;
}
public Test(int intVar) {
this.intVar = intVar;
}
public void myInstanceMethod() {
System.out.println("Hello from instance: " + intVar);
}
public static void main(String[] args) {
Test t = new Test();
IFace i = t::myInstanceMethod;
i.method(); // Hello from instance: 123
t = null; // Nullifying the reference
i.method(); // Hello from instance: 123
// Why still executing the method if reference is nullified?????
t = new Test(456);
i.method(); // Hello from instance: 123
// Why not Hello from instance: 456 ??????
}
static interface IFace {
void method();
}
}
In a sense, the question is similar to asking why printing b does not output null in the following program:
String a = "abc";
String b = a;
a = null;
System.out.println(b);
When IFace i = t::myInstanceMethod; finishes running, i has captured a reference to the object that t points to at this time. That reference is independent from the variable t. Look at it like i, the method reference, has its own variable pointing to the same object.
The memory is not freed when you nullified the reference. It's freed when ALL references are gone. By passing method reference you created new reference to object itself, so the ref count is 2 at that point, i.e. the i holds reference to t underneath
I would like to pass a reference to a primitive type to a method, which may change it.
Consider the following sample:
public class Main {
Integer x = new Integer(42);
Integer y = new Integer(42);
public static void main(String[] args) {
Main main = new Main();
System.out.println("x Before increment: " + main.x);
// based on some logic, call increment either on x or y
increment(main.x);
System.out.println("x after increment: " + main.x);
}
private static void increment(Integer int_ref) {
++int_ref;
}
}
The output running the sample is:
x Before increment: 42
x after increment: 42
Which means int_ref was past to the function by value, and not by reference, despite my optimistic name.
Obviously there are ways to work around this particular example, but my real application is way more complex, and in general one would imagine that a "pointer" or reference to integer would be useful in many scenarios.
I've tried to pass Object to the function (then casting to int), and various other methods, with no luck. One workaround that seems to be working would be to define my own version of Integer class:
private static class IntegerWrapper {
private int value;
IntegerWrapper(int value) { this.value = value; }
void plusplus() { ++value; }
int getValue() { return value; }
}
Doing this, and passing a reference to IntegerWrapper does work as expected, but to my taste it seems very lame. Coming from C#, where boxed variable just remain boxed, I hope I just miss something.
EDIT:
I would argue my question isn't a duplicate of Is Java "pass-by-reference" or "pass-by-value"?, as my question isn't theoretical, as I simply seek a solution. Philosophically, all method calls in all languages are pass-by-value: They either pass the actual value, or a reference to the value - by value.
So, I would rephrase my question: What is the common paradigm to workaround the issue that in java I'm unable to pass a reference to an Integer. Is the IntegerWrapper suggested above a known paradigm? Does a similar class (maybe MutableInt) already exist in the library? Maybe an array of length 1 a common practice and has some performance advantage? Am I the only person annoyed by the fact he can store a reference to any kind of object, but the basic types?
Integer is immutable, as you may notice.
Your approach with private static class IntegerWrapper is correct one. Using array with size 1 is also correct, but in practice I have never seen using array for this case. So do use IntegerWrapper.
Exactly the same implementation you can find in Apache org.apache.commons.lang3.mutable.MutableInt.
In your example you also can provide Main instance to the static method:
public class Main {
private int x = 42;
public static void main(String[] args) {
Main main = new Main();
incrementX(main);
}
private static void incrementX(Main main) {
main.x++;
}
}
And finally, from Java8 you could define an inc function and use it to increment value:
public class Main {
private static final IntFunction<Integer> INC = val -> val + 1;
private int x = 42;
public static void main(String[] args) {
Main main = new Main();
main.x = INC.apply(main.x);
}
}
public class JustPractice {
public int points=0;
public static void main(String args[]) {
JustPractice ha = new JustPractice();
ha.end();
happy();
}
public void end() {
this.points=100;
System.out.println(points);
}
public static void happy() {
JustPractice object = new JustPractice();
System.out.println(object.points);
return;
}
}
The above is displaying:
100 0
whereas it should be displaying:
100 100
You are looking at two different instances of your class.
Every instance gets their own copy of the instance fields, and they are completely independent from each-other.
JustPractice ha = new JustPractice();
ha.end(); // this one has "100"
JustPractice object = new JustPractice(); // this one has "0"
System.out.println(object.points);
The static method can only access ha's instance fields if you provide it with a ha as a parameter.
Make points static. Then you got what you want.
public static int points=0;
make points static will keep only one variable for all instance of your class.
Else each initialization will create separate individual variable and will assign the value to 0
its because of when method is making new object then that time it will having another copy as of the reference object will be having independent copy per object of the class remember the java basic?
and if u will make int as static object then it will give your output what u want and what u asking for simple example from yours is
public static int points = 0;
public void end() {
this.points = 100;
System.out.println(points);
}
public static void happy() {
CheckingClass object = new CheckingClass();
System.out.println(object.points);
return;
}
public static void main(String args[]) {
CheckingClass ha = new CheckingClass();
ha.end();
happy();
}
hope it helpful
it is displaying as 100 0 instead of 100 100 because you are creating a new instance of class JustPractice in your happy() method, instead of passing reference i.e. ha of existing instance.
new newly created instance is showing the default value that that u have given in your class, i.e. 0.
You set value of the points instance variable in end method.and for the object in happy method you don't initialize the points instance variable of object.
So it gets the default value 0.
A static method can access a non-static object, but only if it is passed to the method. Given that the static method in question is the method in which the program begins, you have no ability to pass anything to it.
What it cannot do, within the scope of a non-static class, is access any of the instance members or functions. The problem is not that you're instantiating ha from a static method, it's that you're accessing the member points, which is an instance member that belongs to every instantiation of your class.
In order to fix this, you can either pass points to the instance of JustPractice (ha) that you're creating, and have one of JustPractice's methods return the final value, or you can make points, end() and happy() static as well, in which case all can work happily with one another.
This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 8 years ago.
So as far as I know, in java you can't access objects directly, you only have the pointer to it. So for example I have this code:
public class App {
public App() {
Thing t = null;
doStuff(t);
System.out.println(t);
}
public void doStuff(Thing a) {
a = new Thing();
}
public static void main(String[] args) {
new App();
}
}
class Thing { }
And the output is null. Why? I've passed the pointer to a method which gave it a new Thing instance to point to. Is it because it's a new pointer? Also how can I resolve it without returning anything from doStuff()?
You have references not pointers, and a method cannot update the callers reference without an assignment in the caller - so this
public App() {
Thing t = null;
doStuff(t);
System.out.println(t);
}
public void doStuff(Thing a) {
a = new Thing();
}
Would work if you did,
public App() {
Thing t = null;
t = doStuff(t);
System.out.println(t);
}
public Thing doStuff(Thing a) {
a = new Thing();
return a;
}
This is because Java works by pass by value of Object references and not pass by reference of an Object ,even if the reference is an Object,it still gets passed by the value of reference.So you always work with new references
Refer:http://docs.oracle.com/javase/tutorial/java/javaOO/objectcreation.html
Declaring a Variable to Refer to an Object
Previously, you learned that to declare a variable, you write:
type name; This notifies the compiler that you will use name to refer
to data whose type is type. With a primitive variable, this
declaration also reserves the proper amount of memory for the
variable.
You can also declare a reference variable on its own line. For
example:
Point originOne; If you declare originOne like this, its value will be
undetermined until an object is actually created and assigned to it.
Simply declaring a reference variable does not create an object. For
that, you need to use the new operator, as described in the next
section. You must assign an object to originOne before you use it in
your code. Otherwise, you will get a compiler error.
A variable in this state, which currently references no object, can be
illustrated as follows (the variable name, originOne, plus a reference
pointing to nothing):
on passing object reference to static method m1() why it does not become null and why last statement doesn't give errror. Output is X
class I {
private String name;
public String name() {
return name;
}
public I (String s) {
name = s;
}
}
class J {
public static void m1 (I i){
i = null;
}
public static void main (String[] arg)
{
I i = new I("X");
m1(i);
System.out.print(i.name());
}
}
Java is pass by value so scope of i is limited to m1()
public static void m1 (I i){ // i is copied from i which is in main method but it is another variable whose scope lies within m1() only
i = null; // original i in main lies in main() method scope
}
If you change name of i in method m1(), confusion will be lesser like :
public static void m1 (I iObj){
iObj = null; // i in main() method still points to Object
}
Java uses pass by value exclusively. Changing the value of i within m1 only changes that parameter's value. It doesn't do anything to the variable i within main.
What may confuse you - it certainly confuses plenty of other people - is that although the arguments are passed by value, if the type of the parameter is a class, then that value is a reference... and indeed the value of the i variable in each case is a reference. That reference is still passed by value - the value of the argument is directly copied as the initial value of the parameter. However, if instead of changing the parameter itself you make a change to the object that the parameter value refers to, that's a different matter:
void foo(StringBuilder builder) {
builder.append("Hello");
}
void bar() {
StringBuilder x = new StringBuilder();
foo(x);
System.out.println(x); // Prints Hello
}
See the Java tutorial on passing information to a method or constructor for more details.
Java is pass by value (Read second answer in the link specially)
I i scope of i is limited to method m1 only.
In execution it looks something like:
`I i` in `m1()` points to `null` reference
I i method reference still points to `new I("X");`