好的,这里是JLS专家的一个非常好奇的Java 7语言难题。以下代码不能用javac和Eclipse编译:
package com.example;
public class X {
public static X com = new X();
public void x() {
System.out.println(com.example.X.com);
// cannot find symbol ^^^^^^^
}
}
好像成员com
完全阻止了com.*
内X
个包的访问权限。然而,这并未得到彻底应用。以下工作,例如:
public void x() {
System.out.println(com.example.X.class);
}
我的问题:
请注意,这只是对生成代码中的实际问题的简化,其中需要com.example.X
的完全限定,并且无法重命名com
成员。
更新:我认为它实际上可能是类似这样的问题:Why can't I "static import" an "equals" method in Java?
答案 0 :(得分:6)
This is called obscuring (jls-6.4.2).
简单名称可能出现在可能存在的上下文中 解释为变量,类型或包的名称。在这些 在情况下,§6.5的规则指定将选择变量 优先于类型,并且将优先选择类型 一个包。 因此,有时可能无法参考a 通过简单名称显示可见类型或包装声明。我们这样说 这样的声明模糊不清。
答案 1 :(得分:1)
您的属性com.example.X.com不是静态的,因此无法通过X类以静态方式访问它。您只能通过X的实例访问它。
不仅如此,每次你实现一个X,它都会导致一个新的X:我可以在这里预测内存爆炸。
非常糟糕的代码:)
答案 2 :(得分:1)
如何解决此问题?
在这里使用完全限定的类名可能是个问题,因为通常,包名和变量名都以小写字母开头,因此可能会发生冲突。但是,您不需要使用完全限定的类名来获取类的静态成员的引用;你可以通过类名来引用它。由于类名应以大写字符开头,因此它们不应与包名或变量发生冲突。 (并且您可以使用其完全限定的类名导入任意类而不会出现问题,因为import语句永远不会混淆包名称的变量名。)
public void x() {
// System.out.println(com.example.X.com);
// cannot find symbol ^^^^^^^
System.out.println(X.com); // Works fine
}