11

我今天正在追踪一个错误,我注意到我们的一个班级中有一些奇怪的事情。我剪掉了尽可能多的代码来在这里发布:

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

我想也许它使用 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
0
Exception in thread "main" java.lang.NoSuchMethodError: main

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

4

3 回答 3

8

我只是在我的 IDE 中复制/粘贴了这个,虽然这是一个奇迹,但在尝试保存文件时出现了一条错误消息,清除了这个问题

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

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

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

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

于 2013-07-15T20:04:30.733 回答
6

隐藏的字符。源代码相当于

static int obtainNumber() { return 42; }

static int obtain\ufeffNumber() { return 3; }

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

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

于 2013-07-15T20:58:59.920 回答
1

原来的评论:

如果您注意到,所采用的是与其他语法不同的语法。也许这可能会根据隐藏的字符或语法怪癖为您提供线索。

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

当我看的时候,CP1252没有字节顺序标记,但字符本身在CP1252中。可能输入了杂散的 Unicode 字符。

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

他们是怎么来的,我们永远不会知道。但是,我们确实知道编译器正在使用没有字节顺序标记的那个。

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

我们现在确实需要通过 meta 处理这种 FGITW行为

于 2013-07-15T20:07:20.557 回答