Setting equal in Java: by value or reference?

前端 未结 4 1681
长发绾君心
长发绾君心 2020-12-17 00:29

I did two tests, the first starting with Strings

    String str1 = \"old\";
    String str2 = str1;
    str1 = \"new\";

    System.out.println(         


        
相关标签:
4条回答
  • 2020-12-17 00:39

    In your first code, yes, this line

    String str2 = str1;
    

    Assigns str2 to the same String referred by str1, that is, "old". At this point, they are the same object. However, the next line

    str1 = "new";
    

    create a new instance of String, and changes the reference of str1 to this new String. As we are changing the reference of str1, the content of str2 are not changed.

    Pay attention that Java, Strings are immutable i.e. cannot change state once initialized. Thinking this way, content of "old" may never change. So when you assign "new" to str1, you don't change the value of "old", you create a new String instead.

    In other words, this line, in here, is the same as

    str1 = new String("new");
    

    http://i.minus.com/jboQoqCxApSELU.png

    However, in the second code,

    List<Integer> list2 = list1;
    

    make list2 refer to the same list as list1. As a result, list1 and list2 refer to the same list. Then

    list1.add(1); 
    

    adds an element to the list referred by list1. However, as I have said, list1 and list2 refer to same list, both list1 and list2 now have the element 1. There is no new instance created in the method call.

    http://i.minus.com/jxDLyBqcUzgHZ.png

    In fact, if you were to do

    List<Integer> list1 = new ArrayList<Integer>();
    List<Integer> list2 = list1;
    list1 = new ArrayList<Integer>();
    list1.add(1);
    
    System.out.println(list1.size()); //1
    System.out.println(list2.size()); //0
    

    because list1 = new ArrayList<Integer>(); reassigns list1 to a new list, that no longer refer to the object referred by list2.


    After all the assignment operator (i.e. obj1 = obj2) always copy the references, which two references will still refer to the same object instance after the assignment. This is for both String, List, or any other classes (But not primitive types).

    However, str1 = "new" will, in most cases, create a new instance of String and then assign the reference to the new String to str1 - this is a special case in the Java lanaguage. This don't apply to any other kind of objects. This is different to any other method call like list1.add(1).

    0 讨论(0)
  • 2020-12-17 00:41

    Everything in java is passed by Value.There nothing like pass by refrence in java.Objects reference is passed by value. in ist case ie

    String str1="old"
    String str2=str1; //here str2 is pointed to str1
    str1="new";       // here link of str1 is broken with old and pinted to new location      where as str2 is pointing to same location as earlier.
    

    While in case of list both list are pointing to same memory location so changes are reflected.

    0 讨论(0)
  • 2020-12-17 00:48

    Your difference is here

    str1 = "new";
    

    vs

    list1.add(1);
    

    In the String example, you are changing references. Changing the reference of str1 does not affect any other variables.

    In the List example, you are invoking a method, which dereferences the reference and accesses the object. Any variables referencing that same object will see that change.

    Here it is

    List<Integer> list1 = new ArrayList<Integer>(); // 1
    List<Integer> list2 = list1; // 2 
    list1.add(1); // 3
    

    looks like this

       1:  list1 ===> object1234
       2:  list1 ===> object1234 <=== list2
       3:  list1 ===> object1234 (internal modification) <=== list2
    
    0 讨论(0)
  • 2020-12-17 01:03

    Java is all pass by value. There is no pass by reference with Java. A copy is passed to variables that could be method parameters or regular ordinary variables. Objects such as String literals, Strings, Array references, and ArrayLists will still pass by value.

    The thing is if the reference is not re-assigned then whatever happens to the reference variable will happen to the object it references.

    Check out this tutorial on this from the people that wrote head first java and other books here: http://www.javaranch.com/campfire/StoryPassBy.jsp

    Also with your code, OP, keep in mind that Strings are immutable. This means once the object is created it will not change basically. In your code though the String references are re-assigned while the List reference simply has a method called on it. The List references both point to the exact same ArrayList object; so the method call size() effects both List references since they both point to the same object in heap memory. :D

    Happy Coding!

    0 讨论(0)
提交回复
热议问题