在Java中修改对象引用值的最佳实践?

时间:2012-06-21 23:05:40

标签: java

我对Java很新,最近我正在阅读一些关于Java是按值传递的材料。在我自己运行测试之前,我已经阅读了this questionthis blog

现在,基于我的阅读和快速测试,我发现有两种方法可以改变对象引用中包含的变量。以下哪种方法是更好或更安全的方法?这两种方法都有明显的问题吗?

这两个都打印出“iArr [0] = 45”。

方法1:

public static void main(String args[] ){
   int[] iArr = {1};
   method(iArr) ;
   System.out.println( "iArr[0] = " + iArr [0] ) ;
}
public static void method(int[] n ) { 
    n [0] = 45 ;
}

方法2:

public static void main(String args[] )
{
   int[] iArr = {1};
   iArr = method(iArr) ;
   System.out.println( "iArr[0] = " + iArr [0] ) ;
}
public static int[] method(int[] n ) { 
    n [0] = 45 ;
    return n;
}

2 个答案:

答案 0 :(得分:2)

第二种方法开辟了别名的可能性。

int[] n = {1};
int[] j;

j = method(n);
j[0] = 342;
System.out.println("iArr[0] = " + n[0]);
System.out.println("iArr[0] = " + j[0]);

将打印出来:

iArr[0] = 342
iArr[0] = 342

因此我会在这种情况下选择第一种方法。您只想更改数组,不需要返回引用。如果需要,也可以轻松创建自己的别名。从第二种方法中也不清楚你改变实际参数值,我认为这是非常糟糕的做法。

答案 1 :(得分:2)

我发现既不接近理想,因为它们都会导致相同的副作用

也就是说,它们是相同的,但第二种方法返回修改过的对象:第二种方法仍然修改传入的数组对象!在示例代码中重新分配给#2的返回值iArr对修改的对象没有影响!请记住,Java使用Call-By-Object-Sharing语义(对于引用类型);返回值无关此行为。

我实际上真的不喜欢方法#2,因为它“隐藏”了这个事实(我看着签名并想“哦,我得到一个新的数组对象!” ),虽然方法#1“做了肮脏的工作”,但我可以从void返回类型快速告诉我。 (在某些高级套管中,“链接”可能很有用;这是其中之一。)

这是一个简单的版本,不会引起副作用:(我建议最小化副作用,因为它通常会使代码更易于推理和调试。)

public static void main(String args[] )
{
   int[] iArr = {1};
   int[] newArr = method(iArr) ;
   System.out.println( "iArr[0] = " + iArr [0] ) ;
   // This is different here, but it would "be the same" in the 
   // 2nd-case example in the post.
   System.out.println( "newArr[0] = " + newArr [0] ) ;
}
public static int[] method(int[] n ) {
    // This is a silly stub method, n would be presumably used.
    int[] x = new int[1];
    x[0] = 45; // modifying a DIFFERENT object
    return x;  // returning the NEW object
}