传递对Java方法的引用
我一直在尝试解决一个需要几种方法的问题: 看起来很多,但是你不需要阅读这些方法。只需知道我正在将一个传递对Java方法的引用,java,methods,reference,parameter-passing,Java,Methods,Reference,Parameter Passing,我一直在尝试解决一个需要几种方法的问题: 看起来很多,但是你不需要阅读这些方法。只需知道我正在将一个int[][]]传递给一个方法,在方法内部更改int[][],然后在方法外部检查是否等于int[][] public static boolean One(int[][] matrix){ matrix = transpose(matrix); matrix = reverseRow(matrix); return Arrays.deepEquals(matrix, cha
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;
}
方法一后的原件
0001
0001
0001
0001
这些变化发生在我运行转置(矩阵)和反转(矩阵)之后。请注意,在java调试模式下,当我跨过这些方法时,我可以看到原始代码被更改。我甚至没有提到原创。我修改了一个已通过版本的原始版本
因此,有3个问题:
当您了解到Java变量包含引用而不是对象时,这是最容易理解的 正如前面的问题所讨论的,这些引用总是按值传递的 这个答案解决了你的具体问题 1) 我认为传递给方法的对象不会被更改,除非您返回更改的对象,然后将原始对象设置为changed in main()或原始方法 对象不会传递给方法。Java变量是对对象的引用。可以复制java变量而不复制对象 如果将引用类型的变量传递给方法,则该方法无法修改变量。但是,如果变量引用的对象是可变的,它可以修改该对象 2) 我用一个使用字符串的方法对此进行了测试。我的上述信念是正确的。int[][]是否不同 数组是通过引用访问的可变对象 字符串是一个不可变的对象。您可能试图通过分配给被调用方法的变量来更改调用方的变量 3) 我怎样才能修复它,使原来的不被改变?还是我错过了一些非常简单的东西 在将对数组的引用传递给方法之前,可以创建数组的副本 对一维数组执行此操作的一种方法是使用。二维数组由多个一维数组构成,因此可以使用对
System.arraycopy()
的多个调用来复制它
本问题讨论了其他方法:。请注意,问题中接受的答案省略了创建二维数组的必要步骤。在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
等视为数组上类似于list的mutator方法。为列表设置(0,newValue)
@MLPROGRAMER CiM您的意思是通过值传递。@MLPROGRAMER CiM这是Java,我们的变量包含值,这些值是对对象的引用。当我们将它们传递给方法时,会创建新的引用,这些引用是原始引用的副本。@MLProgrammer CiM,因此,当我们试图解释时,人们仍然感到困惑。@MLProgrammer CiM:正确的术语反映了正确的理解。说到这里:@MLProgrammer CiM-Pshemo不是学究。他正在传达一个对理解Java至关重要的想法,但经常被误解。这个想法对于理解这个问题很重要。如果你来自C++,那么考虑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
}