这两种情况有何不同?

时间:2014-04-05 17:56:06

标签: java parameter-passing

public void otherMethod(){
    List<String> list = new ArrayList<String>();
    list.add("abc");
    list.add("abc");
    list.add("abc");
    someOtherMethod(list);
    System.out.println(list.size());
}

public void someOtherMethod(List<String> list){
    list.add("abc");
}

调用otherMethod打印4。

其中

public void otherMethod(){
    int a = 10
    someOtherMethod(a);
    System.out.println(a);
}

public void someOtherMethod(int a){
    a = 11;
}

打印10;

这两者有何不同。是不是都是局部变量?发送列表参考是否以不同的方式工作?请帮助我理解这两种情况有何不同?

在downvoting之前,请让我理解为什么下面这个也打印10?

public void otherMethod(){
    Long a = new Long(10);
    someOtherMethod(a);
    System.out.println(a);
}

public void someOtherMethod(Long a){
    a = 11;
    //or a= new Long(11);
}

2 个答案:

答案 0 :(得分:2)

事实上,它们在概念上没有区别,在这两种情况下,原始值的副本都作为参数传递给方法。问题在于,在第一种情况下,您具有某种复杂/复合结构,因此您传入的引用副本与原始引用不同,但仍指向原始结构/对象。

在第二种情况下,传入一个int的副本,因此该方法只对复制的int进行操作。与第一种情况不同,该方法通过引用的副本(来自调用者的接收者)直接在原始结构上操作。

现在,在Integer和Long的情况下,您通过复制的引用处理原始对象。问题是你不能对原始对象做太多,因为这些类是不可变的,例如它们没有方法Integer.increment(int n)Long.increment(long n),它们通过递增值来更改原始对象。如果我们谈论String(这是不可变的),但如果我们谈论StringBuilder(因为后者是可变的),那就不一样了。

public void someOtherMethod(Long a){
    a = 11;
    //or a= new Long(11);
}

在此示例中,您将复制的引用指向新对象(11)
但是呼叫者仍然有原始参考,仍然指向
到同一个旧物体(10)。你没办法改变原来的 对象(来自被调用的方法)只是因为Long是不可变的 如果不是,你可以,例如增加它,例如通过致电 a.increment(1)。如果可能的话,这是不同的:你不是 将复制的引用指向新对象,您将其用于调用
原始对象的方法。

请记住,Java是值得传递的(总是),但确实如此 这些差异有时让人感到困惑。

答案 1 :(得分:0)

int不是Java中的对象,因此a不是引用。