代码之家  ›  专栏  ›  技术社区  ›  fluency03

两个URI对象相等,但它们的toString()不相等

  •  1
  • fluency03  · 技术社区  · 8 年前

    我不明白为什么两个文件 URI s是相等的,但 String 代表性不相等。是虫子吗?

    assertEquals(new File(".").toURI(), Paths.get(".").toUri()); // pass
    assertEquals(new File(".").toURI().toString(), Paths.get(".").toUri().toString()); // fail
    
    // org.opentest4j.AssertionFailedError: 
    // Expected :file:/path/to/the/directory/./
    // Actual   :file:///path/to/the/directory/./
    

    更新1

    我理解,从技术上讲,您完全可以实现,其中两个对象基于 equals 方法,但有不同 toString() 后果

    然而,我只是好奇,在课堂上 URI ,它是否是一个良好的实现:两个 URI s相等,但具有不同的字符串表示形式。

    在我的情况下,这是不同的,因为有不同的 getAuthority() 后果但是,为什么他们是平等的呢?这令人困惑。如果我没有打印出结果并检查其源代码,我将不会意识到这一点。

    更新2

    根据@VGR下面的评论,我做了另一个测试,如下所示:

        System.out.println(new File(".").toURI()); // file:/path/to/the/directory/./
        System.out.println(Paths.get(".").toUri()); // file:///path/to/the/directory/./
        System.out.println(new File(".").toURI().getAuthority()); // null
        System.out.println(Paths.get(".").toUri().getAuthority()); // null
    

    如你所见,如果我们 authority 从这两个 URI s、 是的 null 在这两种情况下。

    但是,它们没有相同的 toString() 输出

    3 回复  |  直到 8 年前
        1
  •  1
  •   hoan    8 年前

    这个 URI#toString() 方法记录良好 here :

    以字符串形式返回此URI的内容。 如果此URI是通过调用此类中的一个构造函数创建的,那么将返回一个与原始输入字符串等效的字符串,或者与从原始给定组件计算的字符串等效的字符串(视情况而定)。否则,该URI是通过规范化、解析或相对化创建的,因此根据RFC 2396第5.2节步骤7中指定的规则,从该URI的组件构造一个字符串。

    含义,结果 toString() 方法取决于我们初始化URI对象的方式(总共 5 constructors .)

    在本例中,您试图以两种不同的方式初始化2个URI对象,以便 toString() 它们是不同的。可以尝试 normalize() 方法

        2
  •  0
  •   Juan Rada    8 年前

    若两个对象相等,则不存在这样的约定,字符串表示需要相同。JAVA equals 实施独立于 toString 方法e、 以下类的g实例都是相等的,但它们不具有相同的toString表示。

    public class Foo {
    
        private String value;
    
        @Override
        public boolean equals(Object obj) {
            return true;
        }
    
        @Override
        public String toString() {
            return "value";
        }
    }
    

    在你的特殊情况下 URI 实例是相等的,因为它们指向相同的路径,但字符串表示不同,因为其中一个包含冗余信息。尝试使用 normalize toString之前的方法

        3
  •  0
  •   DanielCuadra    8 年前

    看起来equals方法正在验证它们是否指向相同的 资源 只有但是 统一资源标识符字符串 是不同的,因为它们以两种不同的方式访问相同的资源。

    这就像去商店用1美元的钞票或4个25美分的硬币购买1美元的苏打水:你可以通过不同的方式获得相同的苏打水。收银台的那个家伙说,无论哪种方式付款都一样好,尽管他知道一张钞票和一堆硬币之间有着明显的区别。