getClass()方法返回不同于预期的类

时间:2017-12-12 04:37:59

标签: java junit

我正在使用以下方法从列表中删除重复的路径:

paths.removeAll(Collections.singleton(path));

我在运行Junit测试用例的TestClass.java上运行代码。

Equals和hashcode方法考虑路径对象内的字符串值。

以下代码中的等于方法失败。

    if (getClass() != obj.getClass())
        return false;

即使路径列表中的所有对象都是相同类型的路径。上面的代码无法匹配类名。我看到它将类名称为junit类名称TestClass $ 5 $ 1 $ 1作为第一个值,TestClass $ 5 $ 1 $ 2作为第二个值,因此它失败。

我在这里做错了什么?提前谢谢。

我正在使用以下代码创建路径列表。

Paths paths = new Paths(){
    {
        setPaths(new ArrayList<Path>(){
            {
                add(new Path(){
                    {
                        setValue("c:\\\\test");
                    }
                });
                add(new Path(){
                    {
                        setValue("c:\\\\test1");
                    }
                });
                add(new Path(){
                    {
                        setValue("c:\\\\test1");
                    }
                });
            }
        });
    }
};

如果我使用普通的java代码创建列表“paths”,则equ方法可以正常工作并删除重复路径。

3 个答案:

答案 0 :(得分:1)

此代码创建一个Path的匿名类:

add(new Path(){
    {
        setValue("c:\\\\test");
    }
});

根据您发布的实际Path.equals()代码段,要检查类型兼容性,它并不依赖于instanceof,而是getClass()

 if (getClass() != obj.getClass())
    return false;
 }

所以这两个对象不相等:

Path p1 = new Path(){
    {
        setValue("c:\\\\test");
    }
 }

Path p2 = Paths.get(("c:\\\\test");

由于这些来自两个不同的类:Path类和匿名Path类。

作为解决方法,您可以将路径equals()更改为使用instanceof,例如:

 if (!(obj instanceof Path))
    return false;
 }

但实际上,您不需要创建匿名类。 您应该利用构造函数初始化对象而不是使用初始化器 通过介绍Paths(List<Path> pathes)  和Path(String path)构造函数,你可以这样写:

Paths paths = new Paths(
    new ArrayList<>(Arrays.asList(
        new Path("c:\\\\test"),
        new Path("c:\\\\test1"),
        new Path("c:\\\\test1"))));

答案 1 :(得分:0)

您正在为要实例化的每个对象创建一个独特的匿名类。只需正常创建它们,无需自定义初始化程序块:

Path path1 = new Path();
Path path2 = new Path();
Path path3 = new Path();
path1.setValue("c:\\\\test");
path2.setValue("c:\\\\test1");
path3.setValue("c:\\\\test1");

Paths paths = new Paths();
paths.setPaths(new ArrayList<>(Arrays.asList(path1, path2, path3)));

您可以通过添加构造函数来减少创建和初始化每个Path对象的详细程度:

class Path {
    private String value;

    public Path(String value) {
        this.value = value;
    }
    //...
}

Paths相同:

class Paths {
    private List<Path> paths;

    public Paths(List<Path> paths) {
        this.paths = paths;
    }
    //...
}

现在你可以这样称呼它:

Paths paths = new Paths(Arrays.asList(
        new Path("c:\\\\test"),
        new Path("c:\\\\test1"),
        new Path("c:\\\\test1")));

答案 2 :(得分:-1)

在运行比较类的步骤之前,请尝试使用此if语句或在代码中打印出对象的类类型。

if((obj instanceof Path) == false)
    return false;

我看到你正在尝试从列表中删除单例。 “singleton”方法返回一个Set对象,该对象可能是obj的类型,为什么将Path对象与Set对象进行比较将返回false。但是,它可能不是您正在引用的行失败。 请提供所有引用对象的声明和Path对象的完整equals方法。