编译器如何区分“类名”
因为有两个组件:变量类型和变量名称。声明类型的变量 。类型总是排在第一位。类不是一等对象(意味着您不能对类的引用),除非您进入反射(使用属性)。ClassName
ClassName
.class
因此,在打印语句中:
System.out.println(ClassName);
这只能是变量。 获取一个对象引用,并且您有一个由名为 的变量引用的对象,因此编译器可以解析它。System.out.println
ClassName
我能认为编译器唯一不明确的情况是,如果变量引用的对象具有与类上的静态方法同名的实例方法。
public class SomeClass {
public void aMethod() {
System.out.println("A method!");
}
public static void aMethod() {
System.out.println("Static version!");
}
}
public class TestClass {
public static void main (String[] args) {
SomeClass SomeClass = new SomeClass();
SomeClass.aMethod(); // does this call the instance method or the static method?
}
}
我相信编译器会检测到歧义并以某种指定的方式(在Java规范中)处理它。可能是以下之一:
- 不允许静态方法和实例方法具有相同的名称。
- 允许它,并且在编译时解析引用时,首选实例方法。
- 允许它,并且在编译时解析引用时,首选静态方法。
如果最后2个中的任何一个,我想编译器警告将被记录。
现在撇开编译器问题不谈,代码的唯一另一个消费者是人类。编译器可能能够依靠规范来保证基本原理行为,但人类不能。我们很容易感到困惑。我对此最好的建议很简单,不要这样做!
绝对没有理由将变量命名为与类完全相同的名称。事实上,我见过的大多数Java编码风格约定都使用lowerCamelCase来命名变量和方法,UpperCamelCase来命名类,所以除非你偏离标准,否则它们没有办法发生冲突。
如果我在我正在处理的项目中遇到这样的代码,我会立即重命名变量,然后再执行任何其他操作。
对于我模棱两可的同名实例和静态方法的情况,那里可能还有一个人性的教训:不要这样做!
Java有很多规则可以迫使你做一些合乎逻辑的事情,让代码易于遵循,但归根结底,它仍然是代码,你可以编写任何你想要的代码。任何语言规范或编译器都不能阻止您编写令人困惑的代码。