[英]Passing References to Methods Java
我一直在尝试解决需要两种方法的问题:
它看起来很像,但您实际上并不需要阅读这些方法。 只是知道我正在将int[][]
传递给方法,更改方法内部的int[][]
,然后检查方法外部与int[][]
相等性。
public static boolean One(int[][] matrix){
matrix = transpose(matrix);
matrix = reverseRow(matrix);
return Arrays.deepEquals(matrix, changed);
}
public static boolean Two(int[][] matrix){
//180 degree clockwise
matrix = transpose(matrix);
matrix = reverseRow(matrix);
matrix = transpose(matrix);
matrix = reverseRow(matrix);
return Arrays.deepEquals(matrix,changed);
}
public static int[][] transpose(int[][] matrix){
for(int i = 0; i < N; i++) {
for(int j = i+1; j < N; j++) {
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
return matrix;
}
public static int[][] reverseRow(int[][] matrix){
for(int j = 0; j < N; j++){
for(int i = 0; i < N / 2; i++) {
int temp = matrix[j][i];
matrix[j][i] = matrix[j][N - i - 1];
matrix[j][N - i - 1] = temp;
}
}
return matrix;
}
public static int[][] reverseCol(int[][] matrix){
for(int col = 0;col < matrix[0].length; col++){
for(int row = 0; row < matrix.length/2; row++) {
int temp = matrix[row][col];
matrix[row][col] = matrix[matrix.length - row - 1][col];
matrix[matrix.length - row - 1][col] = temp;
}
}
return matrix;
}
问题的结构如下:我有原始数字的int [] []我有数字的int [] [],这是原始数字转换的结果。 具体而言,顺时针旋转90度,顺时针旋转180度。
实际问题要大得多,但是我认为有一个规则不能直接获得问题的答案,因此我将其缩减为我所需要的。
问题是这样的:运行方法一后,原始数组被修改,因此在运行方法二之前它已损坏。
例如,方法一之前的原始:
1111
0000
0000
0000
方法一之后的原稿;
0001
0001
0001
0001
这些变化发生在我运行transpose(matrix)和reverseRow(matrix)之后。 请注意,在Java调试模式下,当我跳过这些方法时,可以看到原始内容已更改。 我什至没有提到原来的。 我修改了原始版本的通过版本。
因此,有3个问题:
我以为传递给方法的对象不会被更改,除非您返回更改的对象,然后在main()或原始方法中将原始对象设置为更改的对象? 我不是在谈论transpose或reverseRow,因为这些应该在方法One中更改矩阵。
我使用一种使用字符串的方法对此进行了测试。 我的上述信念是正确的。 int [] []不同吗?
我该如何解决它,使原件不变? 还是我错过了一些非常简单的事情?
当您了解Java变量保存引用而不是对象时,这最容易理解。
而且这些引用始终按值传递,如前面的问题中所述, Java是“按引用传递”还是“按值传递”? 。
该答案解决了您的特定问题。
1)我认为传递给方法的对象不会被更改,除非您返回更改的对象,然后将原始对象设置为main()或原始方法中更改的对象?
对象不会传递给方法。 Java变量是对对象的引用 。 您可以复制Java变量而不复制对象。
如果将引用类型的变量传递给方法,则该方法无法修改您的变量。 但是,如果它是可变的,它可以修改变量引用的对象。
2)我测试了使用字符串的方法。 我的上述信念是正确的。 int [] []不同吗?
数组是您要通过引用访问的可变对象。
字符串是一个不可变的对象。 您可能正在尝试通过分配给被调用方法的变量来更改调用者的变量。
3)如何修复它,使原件不被更改? 还是我错过了一些非常简单的事情?
您可以在将数组的引用传递给方法之前制作该数组的副本。
对一维数组执行此操作的一种方法是使用System.arraycopy() 。 您的二维数组是由多个一维数组构成的,因此您可以使用对System.arraycopy()
多次调用来复制它。
此问题讨论了其他方法: 如何在Java中复制二维数组? 。 请注意,问题中接受的答案省略了创建二维数组的必要步骤。
在Java中,一切都是通过值传递的。 但是,令人困惑的是,该值保留了对原始对象的引用 。
分配变量只会更改输入变量的引用:
void doSomething(String str){
str = "New String"; // str variable now holds a reference to "New String"
// however, the original String Object was not changed
}
但是,这不会更改原始字符串。 实际上,String和所有原语int,double等都是一个不可变的对象。这使我得出以下语句:
更改调用函数的输入参数的唯一方法是调用该参数使对象发生突变的方法(例如param.setValue(newValue)
或param[0] = newValue
)。
这使我们可以进行一些观察:
char
, int
, double
等)不能在调用函数中进行更改,因为它们不包含任何使数据变异的方法。 String
, Integer
, Double
等)永远不能在函数中更改,因为根据定义,它们不包含使数据可变的方法。 StringBuilder
, BigInteger
, BigDecimal
等)只能通过在对象上调用mutator方法来更改(而不能通过重新分配变量来更改)。 对于数组,你能想到的array[0] = newValue
等作为上mutator方法Array
类似于list.set(0, newValue)
用于一个List
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.