【问题标题】:getClass() method returning different class than expectedgetClass() 方法返回与预期不同的类
【发布时间】:2017-12-13 01:07:02
【问题描述】:

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

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

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

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

Equals 方法在下面的代码中失败。

    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 代码创建列表“路径”,equal 方法可以正常工作并删除重复路径。

【问题讨论】:

  • 什么是Path?你是如何实例化它的?请发帖minimal reproducible example
  • Path 是其中包含字段值的类。等于和哈希码写在这个字段上。
  • 您能否显示为path 变量赋值的行?以及创建它引用的对象的行?
  • 我知道这是一门课。我们需要查看该类以及您如何实例化它。
  • 添加相关代码后,可以投票重新开启

标签: java junit


【解决方案1】:

这段代码创建了一个Path 的匿名类:

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

根据您发布的实际Path.equals() sn-p,要检查类型兼容性,它不依赖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&lt;Path&gt; pathes)Path(String path) 构造函数,你可以这样写:

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

【讨论】:

    【解决方案2】:

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

    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")));
    

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-27
        • 2015-08-13
        • 2012-01-25
        • 1970-01-01
        相关资源
        最近更新 更多