当前位置: 首页 > 面试题库 >

在Java中设置相等:按值还是引用?

澹台鸿熙
2023-03-14
问题内容

我做了两次测试,第一次是从 Strings

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

    System.out.println(str1); //new
    System.out.println(str2); //old

上面的例子表明 str2 = str1, by value

现在我做类似的操作,但是这次 Lists

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

    System.out.println(list1.size()); //1
    System.out.println(list2.size()); //1

这个例子表明 list2 = list1, by reference

我很困惑,which Java variables/objects被路过了value,哪个路过了reference


问题答案:

在您的第一个代码中,是的,这一行

String str2 = str1;

分配str2给所String引用的str1,即"old"。在这一点上,它们是同一对象。但是,下一行

str1 = "new";

创建的 实例String,并更改str1对此新String 的引用。当我们更改的引用时str1,的内容str2不会更改。

注意Java
String是不可变的,即一旦初始化就无法更改状态。以这种方式思考,内容"old"可能永远不会改变。因此,当您分配"new"给时str1,您不会更改的值"old",而是创建一个新值String

换句话说,这条线在这里与

str1 = new String("new");

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

但是,在第二个代码中

List<Integer> list2 = list1;

使list2list1。参考相同的清单。作为结果,list1list2指向同一个列表。然后

list1.add(1);

将一个元素添加到所引用的列表中list1。但是,正如我刚才所说,list1list2表示相同的列表中,都list1list2现在有元素1。方法调用中没有创建新实例。

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

实际上,如果您要做

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

因为list1 = new ArrayList<Integer>();重新分配list1到新列表,该列表不再引用所引用的对象list2

在所有 赋值运算符(即obj1 = obj2)之后, 总是
复制引用,这两个引用在赋值后仍将引用同一对象实例。这适用于StringList任何其他类 (但不适用于原始类型)。

但是,str1 = "new"在大多数情况下,将创建的新实例,String然后将对新实例的引用分配Stringstr1-在Java语言中这是特例。这不适用于任何其他类型的对象。这与其他任何方法调用(例如)不同list1.add(1)



 类似资料:
  • 问题内容: 我有一个HashMap: 然后我这样做: 第一次打印1000,第二次打印1000,该值不变。为什么Java按值而不是按引用返回Integer? 问题答案: 该方法返回对存储整数的引用的 副本 。 给存储该副本的变量分配一个新值,指向该值将 不会 更改映射中的引用。 如果可以的话,它会工作,但是由于是一个不可变的类,因此这不是一个选择。 如果要使更改在地图中生效,则必须将余额包装在(可变

  • 问题内容: 我读了许多文章,都说Java是通过价值传递的。但是我仍然不能解释按值传递和引用之间的区别。我写了一个示例程序,它像这样执行。 执行 谁能向我解释这些问题… 价值传递是什么意思? 答:它只是将存储在变量中的数字或值传递给函数。我是对还是错。 How do you say Java是通过价值传递? 为什么Java是按值传递而不是按引用传递? 上面的程序Tries是否显示了“按值传递”和“引

  • 问题内容: 我正在寻找一些关于JavaScript何时按值传递值,何时按引用传递,何时修改传递的项目影响函数外部值以及何时不传递值的良好综合阅读材料。我还对何时通过引用与按值分配给另一个变量以及是否遵循除作为函数参数传递以外的任何其他规则进行分配感兴趣。 我已经进行了很多搜索,找到了很多具体的示例(其中很多都在SO上),可以从这些示例中整理出一些真实的规则,但是我还没有找到一个写得很好的文档来描述

  • 问题内容: 我一直认为Java使用传递引用。 但是,我已经看到了几篇博客文章声称不是(博客文章说Java使用值传递)。 我不认为我能理解他们的区别。 有什么解释? 问题答案: Java总是按值传递。 不幸的是,我们根本不处理任何对象,而是处理称为引用的 对象句柄(当然是通过值传递)。选择的术语和语义很容易使许多初学者感到困惑。 它是这样的: 在上面的示例中仍将返回”Max”。值aDog内main未

  • 问题内容: 数组不是Java中的原始类型,但它们也不是对象,因此它们是按值还是按引用传递?它是否取决于数组包含的内容,例如引用或原始类型? 问题答案: 。如果是Array(只不过是Object),则数组引用按值传递。(就像对象引用按值传递)。 当你将数组传递给其他方法时,实际上是复制对该数组的引用。 通过该引用对数组内容进行的任何更改都会影响原始数组。 但是,将引用更改为指向新数组不会更改原始方法

  • 数组在Java中不是一种基元类型,但它们也不是对象,那么它们是通过值传递还是通过引用传递呢?它是否取决于数组包含什么,例如引用或基元类型?