我正在解决一个问题,我发现Java引用并不像我期望的那样工作。当然,我是罪魁祸首:),有人可以请我为什么以下情况发生。我先在这里发布代码。
package misc.matrix;
public class ReferenceTester {
public static void main(String args[]){
Boolean[][] input = {
{true ,false ,true ,true ,false },
{false ,true ,true ,true ,true },
{true ,true ,true ,true ,true },
{true ,true ,true ,true ,true },
{true ,false ,true ,true ,true }
};
print(input);
for(Boolean[] eachRow:input){
for(Boolean eachVal:eachRow){
eachVal = Boolean.TRUE;
}
}
print(input);
/*Expected output
true true true true true
true true true true true
true true true true true
true true true true true
true true true true true
*/
}
/**
* Simply prints the array
*/
private static void print(Boolean[][] input) {
for(Boolean[] outArray:input){
for(Boolean iVal:outArray){
System.out.print(iVal?iVal+" ":iVal+" ");
}
System.out.println();
}
}
}
如果您查看上面的程序,我想要做的就是将Array中的所有值更改为true并打印它。但它只是再次打印输入。 有人可以告诉我为什么会这样。最初我在程序中使用了原始boolean,但由于我不想创建副本,我使用了包装器Boolean Class,它是一个Java OBJECT而不是原语。 (不是每个人都是JAVA OBJECT!?!?!?!?) 为什么会在Java中发生这种情况。为什么不打印所有值都是真的?
请告知。
答案 0 :(得分:6)
您无法修改foreach循环中的源对象。你的循环必须是这样的循环标准:
for(int i = 0; i < input.length; i++){
for(int j = 0; j < input[i].length; j++){
input[i][j] = true;
}
}
修改:更准确地说,循环中的eachVal
是指针,而不是引用;因此将其设置为指向不同的值不会更改原始值。
foreach循环在幕后使用的确切形式为here,如果您想独立确认。
答案 1 :(得分:2)
你的问题是循环改变数组的值:
for(Boolean[] eachRow:input){
for(Boolean eachVal:eachRow){
eachVal = Boolean.TRUE;
}
}
在每次迭代中,变量eachVal
保存对数组单元格内容的引用,正如您所期望的那样。但问题是,因为Boolean
是一个不可变的类型 - 也就是说,你不能在创建Boolean
对象之后改变它的值 - 你的任务不起作用。实际上,您实际所做的是更改eachVal
引用指向的对象。也就是说,由于eachVal
是来自input
和eachRow
的独立变量,因此您只需重新分配此变量,而无需触及数组的内容。
如果您希望我扩展或澄清任何特定观点,请告诉我。
答案 2 :(得分:1)
@mmyers得到了答案,你要求提供更多详细信息,但我无法将其纳入评论:
所以你有一个对布尔值的引用数组(它是ALWAYS引用),在你的每个循环中你创建一个引用,指向与该数组成员相同的布尔值。
每次迭代都会更新引用以指向数组中的下一个指针指向的内容。
当您使用equals时,您只需重新指定引用以指向其他内容。
如果你想更新数组中的对象,它必须是可变的(布尔不是),你必须使用mutator而不是equals。
答案 3 :(得分:1)
您尝试的内容类似于以下内容:
int[] arr = { 1, 2, 3 };
for (int i : arr) {
i = 0;
}
这不会将数组中的所有值都设置为0. Java会按值传递所有值。