java 为什么下面程序的输出是这样的?[副本]

fnatzsnv  于 2023-05-15  发布在  Java
关注(0)|答案(2)|浏览(109)

此问题已在此处有答案

Is Java "pass-by-reference" or "pass-by-value"?(90答案)
7小时前关闭
考虑下面的程序

class A{
    public void foo0(){
        ArrayList<Integer> tmp = new ArrayList<>();
        tmp.add(1);
        System.out.println(tmp.size());
        
        foo1(tmp);
        
        System.out.println(tmp.size());
        
        foo2(tmp);
        
        System.out.println(tmp.size());
    }
    
    public void foo1(ArrayList<Integer> tmp){
        tmp = new ArrayList<>();
    }
    
    public void foo2(ArrayList<Integer> tmp){
        tmp.add(4);
    }
}
public class Main
{
    public static void main(String[] args) {
        A obj = new A();
        obj.foo0();
        
    }
}

我的预期答案是101,因为考虑到通过参考方案。但实际输出不同输出:- 1 1 2

u4dcyp6a

u4dcyp6a1#

好的,你们知道在Java中,当你把一个对象传递给一个方法时,你实际上只是给它一个指向原始对象的“方向”,对吧?就像,你没有给它实际的对象,只是一种找到它的方法。这就是我们所说的参考。
现在,在foo 1()方法中,您正在获取这些方向,将它们揉成一团,然后将它们抛出。你说,“我不在乎你指的是哪里,现在你指的是我刚做的这个全新的ArrayList。”但问题是,这对foo 0()中的原始ArrayList没有任何影响。在那里,什么都没有改变,因为foo 1()只处理了它自己的方向的本地副本。
但是在foo 2()中,情况就不同了。在那里,你没有改变tmp的指向。你只是沿着那个地方,添加一些新的东西。所以当你回到foo 0()时,你可以看到这个变化。
所以,当你运行整个过程时:
你从一个大小为1的ArrayList开始。foo 1()不会改变原始ArrayList的任何内容,所以它的大小仍然是1。foo 2()添加另一个元素,将大小提升到2。所以你看到的是112而不是101。希望能帮到你,伙计!如果你还有什么想知道的就告诉我。

bz4sfanl

bz4sfanl2#

你在Java的工作原理上有一些根本的差距,但让我向你解释一下:
1.你加上数字1,列表中就有了1个元素,所以大小是“1”
1.调用foo1,初始化对一个空的新ArrayList的引用,这就是在第二个println中有“0”的原因
1.在foo2中添加一个元素并再次打印大小,这就是使用“1”作为大小的原因

相关问题