【发布时间】:2018-07-22 07:39:00
【问题描述】:
我不明白final 关键字在用于方法参数时真的在哪里很方便。
如果我们排除匿名类的使用、可读性和意图声明,那么对我来说几乎毫无价值。
强制某些数据保持不变并不像看起来那么强大。
如果参数是原始参数,那么它将不起作用,因为参数是作为值传递给方法的,并且在范围之外更改它不会产生任何影响。
如果我们通过引用传递参数,那么引用本身就是一个局部变量,如果从方法内部更改引用,则不会从方法范围之外产生任何影响。
考虑下面的简单测试示例。 尽管该方法更改了给它的引用的值,但该测试通过了,但没有任何效果。
public void testNullify() {
Collection<Integer> c = new ArrayList<Integer>();
nullify(c);
assertNotNull(c);
final Collection<Integer> c1 = c;
assertTrue(c1.equals(c));
change(c);
assertTrue(c1.equals(c));
}
private void change(Collection<Integer> c) {
c = new ArrayList<Integer>();
}
public void nullify(Collection<?> t) {
t = null;
}
【问题讨论】:
-
关于术语的快速说明 - Java 根本没有传递引用。它具有传递引用按值,这不是一回事。使用真正的引用传递语义,您的代码结果会有所不同。
-
按引用传递和按值传递引用有什么区别?
-
在 C 上下文中描述这种差异更容易(至少对我而言)。如果我将指针传递给类似的方法:
int foo(int <i>bar)</i>,则该指针是按值传递的。意味着它被复制了,所以如果我在该方法中做一些事情,比如free(bar); bar = malloc(...);那么我刚刚做了一件非常糟糕的事情。 free 调用实际上会释放指向的内存块(所以我传入的任何指针现在都悬空了)。但是,int foo(int &bar)表示代码有效,传入的指针的值会发生变化。 -
第一个应该是
int foo(int* bar),最后一个应该是int foo(int* &bar)。后者是通过引用传递指针,前者是通过值传递引用。 -
@Martin,在我看来,这是一个很好的问题;请参阅问题的标题和帖子内容,以解释为什么提出 question。可能我对这里的规则有误解,但这正是我在搜索"uses of final parameters in methods"时想要的问题。
标签: java pass-by-reference final pass-by-value