在Java中将多个变量初始化为相同的值

264

我正在寻找一种干净高效的方法来声明相同类型和相同值的多个变量。目前我的代码如下:

String one = "", two = "", three = "" etc...

但我正在寻找类似于:

String one,two,three = ""

这是Java中可能实现的事情吗?保持效率在考虑范围内。


7
谨记效率。效率指的是什么? - khachik
24
代码长度、打字时间、视觉简单。这就是我的意思。我知道保留内存就是保留内存,而这个问题与“人类”方面有关。 - user83643
1
我认为这通常违反了Java的惯例,会让读者感到惊讶,并且在我看来比将它们分别声明在不同行中更难阅读。 - Simeon
4
我检查了 (在Java 8上的) 表现,a = b = c = d = e = true 比 a = true; b = true; 等花费的时间要长2倍。 - Amit Kumar Gupta
@AmitKumarGupta 我在JDK16上测试了一下,使用JMH并没有发现明显的差异。你是怎么测试的呢?另外,一旦你给one、two、three分配了除常量以外的其他值,它们就变成了相同的(多重赋值)。实际上,在处理多线程代码时,可以利用多个变量赋值,因为DUP使用堆栈。 - Adam Gent
7个回答

385
String one, two, three;
one = two = three = "";

这应该适用于不可变对象。对于可变对象来说是没有任何意义的,比如:

Person firstPerson, secondPerson, thirdPerson;
firstPerson = secondPerson = thirdPerson = new Person();

所有变量将指向同一个实例。在这种情况下,你可能需要的是:

Person firstPerson = new Person();
Person secondPerson = new Person();
Person thirdPerson = new Person();

或者更好的方法是使用数组或Collection


17
有些情况下,这也适用于可变对象。例如,在链表实现的构造函数中,最初head和tail都指向new Node(value)创建的同一个节点,因此head和tail应该指向相同的引用。 - bcorso
这两个对象是相同的吗?如果我之后执行 one = "cat"two.equals("cat") 会返回 true 吗? - Aequitas
唯一的注意事项是,这对于静态变量不起作用。 - IgorGanapolsky
整数声明怎么样? - IgorGanapolsky
为什么使用日历时这个不起作用?如果您对它们进行操作,则每个变量的行为都像是相同的。 - TheCrazyProfessor

75

你可以声明多个变量,也可以初始化多个变量,但不能同时进行:

 String one,two,three;
 one = two = three = "";

但是,这种做法(尤其是多重赋值)会被大多数Java开发人员所不赞同,他们认为这恰恰是“视觉简单”的相反方式。


32
+1 是为了指出他试图做的不是常规做法。 - Brian Roach
1
这是关于字符串的,但整数怎么办?int day,month,year,hour,min = day = month = year = hour = 0; 这样对吗? - Ranjit

28

不,Java中不可能实现这个功能。

你可以这样做... 但尽量避免使用它。

String one, two, three;
one = two = three = "";

14
你能解释一下为什么应该避免这个吗? - Neuron
@Lonely Neuron 我认为如果你这样使用很容易犯错误。 - Yuhang Lin
5
@YuhangLin,我只是希望能得到一个更好的回答。 - Neuron
@LonelyNeuron 首先,它速度较慢。初始化时间几乎是分别初始化的两倍。其次,“这个特性”是不必要的。我想不出任何一种情况不能使用其他方法来解决。简单地说,这不是一个干净的代码。 - Alexander Heim
2
@AlexanderHeim 感谢您的解释。但我之所以问是因为它应该是答案的一部分。 - Neuron
2
@AlexanderHeim 为什么它变慢了? - Cristian Gutu

23

适用于基本数据类型和不可变类,例如 String、包装类 Character 和 Byte。

int i=0,j=2   
String s1,s2  
s1 = s2 = "java rocks"

对于可变类

Reference r1 = Reference r2 = Reference r3 = new Object();`  

创建了三个引用和一个对象。所有的引用都指向同一个对象,你的程序将会出现错误行为。


4
我不同意"All references pointing to same object and your program will misbehave."这句话。唯一的问题是一个引用所指向对象的变化会同时反映到其它指向同一对象的引用上,因为它们指向的是同一个对象。这并不是程序运行出现了错误,而是Java的工作原理。 - GKFX
1
“misbehave”是什么意思?它的行为会与3个单独初始化的对象不同,但这实际上取决于你想要什么。 - Neuron

17

你可以这样做:

String one, two, three = two = one = "";

但是它们将指向同一个实例。这不会对最终变量或原始类型造成问题。通过这种方式,您可以在一行中完成所有操作。


这也适用于最终变量。例如:public static final String ONE, TWO = ONE = "Blah"; 不仅所有变量都定义并初始化为相同的值,而且变量ONE的分割定义和赋值不违反最终限制;它被视为单个表达式。 - Yurelle

2

我认为不可能一次性设置所有值(就像你提供的第一个示例)。

你给出的第二个示例只会将最后一个变量初始化为空字符串,而不是其他变量。


1
编辑:正如Zeeen指出的那样,这在Java中不起作用。我本打算回答的问题也是关于Groovy的,这是我的错误提交。

虽然有点晚了,但我发现最简单的方法是:

String foo = bar = baz = "hello"
println(foo)
println(bar)
println(baz)

输出:

hello
hello
hello

@Zeeen 在你的 Groovy 解释器中试一下! - starscream_disco_party
这是Groovy,不是普通的Java。它也不能在常规的Java上运行,我刚测试了一下。 - Zeeen
啊,看那个,我提交这个答案的时候可能把一些标签搞混了。至少它似乎帮助了其他一些困惑的人 ¯\(ツ) - starscream_disco_party

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接