“==”改变getClass()的结果?
" == " change results of getClass()?
我实现了这样的 equals() 方法
public boolean equals(Object y) // does this board equal y?
{
if (y == null) return false;
if (this == y) return true;
if (this.getClass() != y.getClass()) return false;
Board that = (Board) y;
return Arrays.equals(this.newblocks, that.newblocks);
}
我使用
测试了这个方法
Board initial = new Board(newblocks);
Board initial2 = new Board(newblocks);
StdOut.println(initial.equals(initial2));
然而,结果是假的。我发现在 y == null 这一行之后,y 的 class 从 Board 变成了 string。为什么会这样?
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
编辑:
这是一个 MVCE。
import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;
import java.util.Arrays;
public final class Board {
private int[][] newblocks;
public Board(int[][] blocks) // construct a board from an n-by-n array of newblocks
{
newblocks = new int[blocks.length][blocks.length];
// this.blocks = new int[blocks.length][blocks.length];
for (int i = 0; i < blocks.length; i++)
for (int j = 0; j < blocks.length; j++)
newblocks[i][j] = blocks[i][j];
}
public int dimension() // board dimension n
{ return newblocks.length; }
public boolean equals(Object y) // does this board equal y?
{
if (y == null) return false;
if (this == y) return true;
if (this.getClass() != y.getClass()) return false;
Board that = (Board) y;
return Arrays.equals(this.newblocks, that.newblocks);
}
public String toString() // string representation of this board (in the output format specified below)
{
StringBuilder s = new StringBuilder();
s.append(dimension());
s.append("\n");
for (int i = 0; i < dimension(); i++) {
for (int j = 0; j < dimension(); j++) {
s.append(newblocks[i][j]);
s.append("\t");
}
s.append("\n");
}
return s.toString();
}
public static void main(String[] args) // unit tests (not graded)
{
In in = new In(args[0]);
int n = in.readInt();
int[][] newblocks = new int[n][n];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
newblocks[i][j] = in.readInt();
Board initial = new Board(newblocks);
Board initial2 = new Board(newblocks);
StdOut.println(initial);
StdOut.println(initial.equals(initial2));
}
}
测试文档是类似
的txt文件
3
1 2 3
0 4 8
7 6 5
第一个“3”表示它是一个3x3的矩阵,后面的九个数字属于矩阵。
==
运算符永远不会改变任何东西,更不用说 class。
您的错误隐藏在其他地方(很可能在您尚未发布的代码中)。
I found after the line y == null, the class of y change from Board to string.
我可以明确地说你错了。您所描述/提出的是不可能 Java。 object 的基本类型(由 this.getClass()
返回)不会改变。从来没有1.
必须的是 y
首先不是 Board
的实例。
或者,您向我们展示的代码与现实不匹配2。
如果您想让我们理解/解释实际上 发生了什么,您需要写一个MVCE 并与我们分享。 (而且我怀疑这样做的过程会揭示......给你......真正的问题是什么。)
1 - 由于 y
是局部变量,因此即使是内存可见性异常也无法做到这一点。发生这种情况的唯一方法是,如果您编写了一些从不同线程践踏 object headers 的本机代码。如果你做那种事情,你的 JVM 很容易崩溃。
2 - 例如,您可能正在调用 equals
的不同重载,或者您可能错误地转录或简化了代码,或者您可能 运行不同版本的代码。
更新
当我调试你的程序时,很明显代码没有在这一行返回 false
:
if (this.getClass() != y.getClass()) return false;
实际上是对 Arrays.equals
的调用返回了 false。
原因是 Arrays.equals(Object[], Object[])
并没有按照您认为的方式比较一对 int[][]
object。 (仔细阅读 javadoc,思考 Object[]
实例的元素实际上是什么......以及它们的 equals
方法将做什么。)
提示:Arrays.equals 对您的尝试无效。
Arrays.equals()
使用 equals()
比较每个元素。由于在您的情况下,这些元素本身就是数组,因此相等性检查失败。解决方案是使用Arrays.deepEquals()
,它将比较任意深度的数组元素。
我实现了这样的 equals() 方法
public boolean equals(Object y) // does this board equal y?
{
if (y == null) return false;
if (this == y) return true;
if (this.getClass() != y.getClass()) return false;
Board that = (Board) y;
return Arrays.equals(this.newblocks, that.newblocks);
}
我使用
测试了这个方法 Board initial = new Board(newblocks);
Board initial2 = new Board(newblocks);
StdOut.println(initial.equals(initial2));
然而,结果是假的。我发现在 y == null 这一行之后,y 的 class 从 Board 变成了 string。为什么会这样?
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
编辑:
这是一个 MVCE。
import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;
import java.util.Arrays;
public final class Board {
private int[][] newblocks;
public Board(int[][] blocks) // construct a board from an n-by-n array of newblocks
{
newblocks = new int[blocks.length][blocks.length];
// this.blocks = new int[blocks.length][blocks.length];
for (int i = 0; i < blocks.length; i++)
for (int j = 0; j < blocks.length; j++)
newblocks[i][j] = blocks[i][j];
}
public int dimension() // board dimension n
{ return newblocks.length; }
public boolean equals(Object y) // does this board equal y?
{
if (y == null) return false;
if (this == y) return true;
if (this.getClass() != y.getClass()) return false;
Board that = (Board) y;
return Arrays.equals(this.newblocks, that.newblocks);
}
public String toString() // string representation of this board (in the output format specified below)
{
StringBuilder s = new StringBuilder();
s.append(dimension());
s.append("\n");
for (int i = 0; i < dimension(); i++) {
for (int j = 0; j < dimension(); j++) {
s.append(newblocks[i][j]);
s.append("\t");
}
s.append("\n");
}
return s.toString();
}
public static void main(String[] args) // unit tests (not graded)
{
In in = new In(args[0]);
int n = in.readInt();
int[][] newblocks = new int[n][n];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
newblocks[i][j] = in.readInt();
Board initial = new Board(newblocks);
Board initial2 = new Board(newblocks);
StdOut.println(initial);
StdOut.println(initial.equals(initial2));
}
}
测试文档是类似
的txt文件3
1 2 3
0 4 8
7 6 5
第一个“3”表示它是一个3x3的矩阵,后面的九个数字属于矩阵。
==
运算符永远不会改变任何东西,更不用说 class。
您的错误隐藏在其他地方(很可能在您尚未发布的代码中)。
I found after the line y == null, the class of y change from Board to string.
我可以明确地说你错了。您所描述/提出的是不可能 Java。 object 的基本类型(由 this.getClass()
返回)不会改变。从来没有1.
必须的是 y
首先不是 Board
的实例。
或者,您向我们展示的代码与现实不匹配2。
如果您想让我们理解/解释实际上 发生了什么,您需要写一个MVCE 并与我们分享。 (而且我怀疑这样做的过程会揭示......给你......真正的问题是什么。)
1 - 由于 y
是局部变量,因此即使是内存可见性异常也无法做到这一点。发生这种情况的唯一方法是,如果您编写了一些从不同线程践踏 object headers 的本机代码。如果你做那种事情,你的 JVM 很容易崩溃。
2 - 例如,您可能正在调用 equals
的不同重载,或者您可能错误地转录或简化了代码,或者您可能 运行不同版本的代码。
更新
当我调试你的程序时,很明显代码没有在这一行返回 false
:
if (this.getClass() != y.getClass()) return false;
实际上是对 Arrays.equals
的调用返回了 false。
原因是 Arrays.equals(Object[], Object[])
并没有按照您认为的方式比较一对 int[][]
object。 (仔细阅读 javadoc,思考 Object[]
实例的元素实际上是什么......以及它们的 equals
方法将做什么。)
提示:Arrays.equals 对您的尝试无效。
Arrays.equals()
使用 equals()
比较每个元素。由于在您的情况下,这些元素本身就是数组,因此相等性检查失败。解决方案是使用Arrays.deepEquals()
,它将比较任意深度的数组元素。