Java如何区分具有相同名称/签名的多个方法?

Java如何区分具有相同名称/签名的多个方法?,java,unicode,polymorphism,Java,Unicode,Polymorphism,今天我在追踪一个bug,我注意到我们班上有一个奇怪的东西。我剪下尽可能多的代码在这里发布: class A { static int obtainNumber() { return 42; } static int obtainNumber() { return 3; } static int obtainNumber() { return -1; } static { System.out.println(obtainNumber());

今天我在追踪一个bug,我注意到我们班上有一个奇怪的东西。我剪下尽可能多的代码在这里发布:

class A {
    static int obtainNumber() { return 42; }
    static int obtainNumber() { return 3; }
    static int obtainNumber() { return -1; }
    static {
        System.out.println(obtainNumber());
    }
}
这个类有3个方法,它们的名称和签名完全相同。起初我认为这是无效代码,但后来eclipse会用红色突出显示代码。它确实有效:

javac A.java && java A
42
Exception in thread "main" java.lang.NoSuchMethodError: main
所以我想也许Java会使用它看到的第一个。我重新排序以测试:

class A {
    static int obtainNumber() { return 3; }
    static int obtainNumber() { return -1; }
    static int obtainNumber() { return 42; }
    static {
        System.out.println(obtainNumber());
    }
}
不,同样的结果:

javac A.java && java A
42
Exception in thread "main" java.lang.NoSuchMethodError: main
javac A.java && java A
0
Exception in thread "main" java.lang.NoSuchMethodError: main
我想也许它用的是42,因为它是最大的。为了测试这一点,我采用了原始值并更改了返回值:

class A {
    static int obtainNumber() { return 0; }
    static int obtainNumber() { return 1; }
    static int obtainNumber() { return 2; }
    static {
        System.out.println(obtainNumber());
    }
}
它仍然知道使用第一个:

javac A.java && java A
0
Exception in thread "main" java.lang.NoSuchMethodError: main
如果我再次对它们进行排序:

class A {
    static int obtainNumber() { return 1; }
    static int obtainNumber() { return 0; }
    static int obtainNumber() { return 2; }
    static {
        System.out.println(obtainNumber());
    }
}
同样的结果:

javac A.java && java A
42
Exception in thread "main" java.lang.NoSuchMethodError: main
javac A.java && java A
0
Exception in thread "main" java.lang.NoSuchMethodError: main

我认为Java是一种基于文本的语言,我想这会使这类事情变得不可能。Java如何跟踪哪种方法是哪种方法?

我刚刚在我的IDE中复制/粘贴了该方法,尽管这是一个奇迹,但在尝试保存文件时,出现了一条错误消息,清除了此问题:

无法完成保存。尝试文件>另存为。。。如果问题仍然存在

原因: 某些字符无法使用“Cp1252”字符编码进行映射。 更改编码或删除“Cp1252”字符编码不支持的字符

因此,这些方法没有相同的名称,只是使用看起来相同的字符

有关Java源文件上字符编码的更多信息:

  • (作者)
    • 我的原始评论:


      如果您注意到,所采取的是一个不同于其他语法的。也许这会根据隐藏的字符或语法怪癖给你提供线索

      我将这个粘贴到Eclipse中,并注意到了一个额外的字符。我将保存的文件(在CP1252中)放入一个十六进制编辑器,并找到一个字节顺序标记

      当我查看时,CP1252没有字节顺序标记,但是字符本身在CP1252中。可能输入了一个游离的unicode字符

      当我仔细观察时,另一个方法在另一个字节顺序中有另一个字节顺序标记

      他们是怎么来的,我们永远也不知道。但是,我们知道编译器使用的是没有字节顺序标记的


      您应该检查项目是否存在编码问题,尤其是从其他系统类型或可能有故障或暴露于旧设备的旧存储介质中恢复的项目


      我们现在真的需要在某个时候通过meta处理这种FGITW行为。

      隐藏字符。源代码相当于

      static int-obtainNumber(){return 42;}

      static int-get\ufeffNumber(){return 3;}

      static int-get\ufeff\ufeffNumber(){return-1;}


      为了避免此类问题,我的源文件严格使用US-ASCII。我想确定我看到的字符正是编译器看到的字符。

      如果您注意到了,所使用的字符就是语法与其他字符不同的字符。也许这会根据隐藏的字符或语法怪癖给你提供线索。为什么会有人这样做?这就像是一个在地球上玩的魔术programmer@Jim来自蝙蝠侠黑暗骑士:有些人只是想看着世界燃烧。因此,我产生了很多坏想法。你应该检查项目的编码问题,特别是如果它是从其他系统类型或可能有故障或暴露于携带瘟疫的旧设备的旧存储介质中恢复的。