我有点困惑,希望有人可以对此事有所了解。我创建了一个函数,从图像数组中删除水平线,并返回没有任何水平线的图像数组。但是当我用我的图像数组调用这个函数时,它也直接修改了我传递它的图像数组。为什么会这样?
int[][] imageArray = ImageToArray();
int[][] _NoLines = RemovedLines(imageArray);
imageArray
应该仍然有正确的行吗?
如果有人好奇,这是实际的功能:
public int[][] RemovedLines(int[][] _baseImage)
{
int width = _baseImage[0].length, height = _baseImage.length;
int white = 0;
int black = 0;
for (int y = 0; y < height; y++) {
white = 0;
black = 0;
for (int x = 0; x < width; x++) {
if(_baseImage[y][x] == 0xFFFFFFFF){
white++;
}else{
black++;
}
}
if(black > white)
{
// line detected fist time
// now get height of line
int _starts = y;
_starts++;
int _end = 0;
for(; _starts < height; _starts++){
white = 0;
black = 0;
for(int _x = 0; _x < width; _x++){
if(_baseImage[_starts][_x] == 0xFFFFFFFF){
white++;
}else{
black++;
}
}
if(white > black){
// end of line height
_end = _starts;
_starts = y;
break;
}
}
white = 0;
black = 0;
for(;_starts < _end; _starts++){
for(int line = 0; line < width; line++){
if(_baseImage[_starts-1][line] != 0xFF000000
&& _baseImage[_starts-2][line] != 0xFF000000
|| _baseImage[_starts+1][line] != 0xFF000000
&& _baseImage[_starts+2][line] != 0xFF000000){
_baseImage[_starts][line] =0xFFFFFFFF;
}
}
}
y = _end;
}
}
return _baseImage;
}
答案 0 :(得分:3)
在Java数组中是对象。将对象传递给方法时,传递给该方法的值是其引用的副本。这会导致对对象的修改,作为参数传递给方法,对对象的引用进行修改,从而改变对象。
关于我在遇到的基元和对象上通过值传递Java的最佳描述之一是Java Ranch上的story。
答案 1 :(得分:1)
java中的数组是对象。
这就像传递了一个指向数组的指针,但不是原始指针,而是它的副本。
您修改了数组的内容 您必须在方法中创建一个新的Array。 在该副本中,您可以删除这些行 然后你返回那份副本。
答案 2 :(得分:0)
正如其他人所指出的,数组是对象和:
Java将对象作为值传递的引用传递
引用:Is Java "pass-by-reference" or "pass-by-value"?
这意味着,当您输入方法RemovedLines
时,_baseImage
是一个引用,指向与imageArray
相同的对象(两个不同的引用指向堆中的同一个对象) )。
因此,您的第一步应该是创建原始数组的副本。方法如下:
int[][] cloneArray = new int[_baseImage.length][];
for (int i = 0; i < cloneArray.length; i++) {
cloneArray[i] = _baseImage[i].clone();
}
由于_baseImage
是通过值传递的引用,因此您甚至可以执行以下操作:
_baseImage = cloneArray;
从_baseImage
开始RemovedLines
内imageArray
将独立于主cloneArray
数组(每个引用将指向堆中的不同对象)。
但请注意,这将使大多数Java开发人员想要伤害你(它带回了关于SCJP / OCPJP考试的错误记忆)。 正如@AlexWien指出的那样,推荐的方法是重构代码以使其工作{{1}}并将其返回。