我对Java很新,最近我正在阅读一些关于Java是按值传递的材料。在我自己运行测试之前,我已经阅读了this question和this 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;
}
答案 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
}