TL;DR
在我个人看来,无需开发人员额外努力即可自动将数据结构作为引用传递的语言应归类为按引用传递,因为指向过时的标准并不能真正帮助任何人.
关于按值传递与按引用传递的争论
技术上 Java 是按值传递的
参考:Is Java "pass-by-reference" or "pass-by-value"?
但是,由于该值通常最终成为一个指针(除非您传递的是原始类型),它也可以通过引用传递。
如今,按引用传递的语言几乎不存在,而且往往不告诉某人一种语言是按值传递的,这对回答他们的问题没有多大帮助,实际上可能会给他们错误的想法首先学习如何编码。
参考:What (are there any) languages with only pass-by-reference?
一般来说,大多数人想知道的是我的数据在哪里以及它是如何传递的。由于像 Java 和 Python 这样的语言不给你选择指向数据的指针(不,反射不算数),它提出了一个问题,如果我创建一个传递类型 Foo 的函数,它会复制值吗在整个 Foo 对象中,或者只是引用同一个 foo 对象。
分别以这两个非常相似的 C 和 Java 程序为例。
struct {
int bar;
} Foo;
void editFoo(Foo foo) {
foo.bar = 85;
Foo a;
a.bar = 6;
editFoo(a);
printf("bar: %d", a.bar);
class Foo {
int bar;
}
static void editFoo(Foo foo) {
foo.bar = 85;
}
Foo a = new Foo();
a.bar = 6;
editFoo(a);
System.out.println("bar: " + a.bar);
C版打印6,说明函数没有修改a。为了让它改变a 中的数据,我们需要修改函数以指定它需要一个引用。然而另一方面,Java 版本打印 85 表明它确实通过了引用,而我们没有任何额外的工作。事实上,Java 并没有像 C 那样提供按值传递的选项。如果我想传递一个完全独立但相同的Foo 副本,我需要创建一个deepCopy 函数并在每次传递对象时调用它。在我看来,这就是传递值和传递引用的区别。
所以回答你的问题...
您可以将其添加到构造函数或通过函数调用传递。
public class Numbers {
public static void modifyList(ArrayList<ArrayList<String>> list) {
// You can access it here too!
list.get(0).add("two");
}
}
// Somewhere in main function
Numbers.modifyList(stats);
System.out.println(list.get(0).get(0));
// Should output "two"
不过,您可能会在当前代码中遇到问题,因为 stats 不是 static,而是在 static 上下文中使用。