- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
今天,我查看了相同的Android代码,发现了一个奇怪的现象。
是匿名内部类直接调用外部类实例方法。
在我看来,直接调用方法就相当于加上this
就在该方法之前,并且 this
是内部类的实例。
按照这个逻辑,在匿名内部类中直接调用外部类的实例,就会导致编译错误。
但是实际编译这个应用程序,并没有问题。并且运行日志正常。
因此,写一个简单的Demo来验证之前的概念是错误的。代码如下:
public class InnerClass {
public static void main(String[] args) {
new InnerClass().process();
}
public void process() {
new Thread() {
@Override
public void run() {
System.out.println(toString("test"));
}
}.start();
}
public String toString(String string) {
return string;
}
}
那么,OpenJDK和Oracle中匿名内部类直接调用外部类实例方法有什么区别呢?
在哪里可以找到文档来了解这些差异?
我很努力,但没有得到明确的答案。
谢谢。
附注
根据我的观点
public class InnerClass {
public static void main(String[] args) {
new InnerClass().process();
}
public void process() {
new Thread() {
@Override
public void run() {
// In According to my point of view
// toString("test")
// <==>
// this.toString("test")
// and `this` is the instance of Thread
// what's the error of my view?
System.out.println(toString("test"));
}
}.start();
}
public String toString(String string) {
return string;
}
}
最佳答案
问题在于
public void run() {
System.out.println(toString("test"));
}
正在匿名Thread
子类上调用toString
,即Thread::toString()
。没有 Thread::toString(String)
,并且不考虑封闭范围中的 toString(String)
方法。
JLS 声明,如果内部类中没有具有所需名称的方法,它只会检查封闭/外部类的方法。请参阅JLS 15.12.1 :
If the form is MethodName, that is, just an Identifier, then:
If the Identifier appears in the scope of a visible method declaration with that name (§6.3, §6.4.1), then:
If there is an enclosing type declaration of which that method is a member, let T be the innermost such type declaration. The class or interface to search is T.
This search policy is called the "comb rule". It effectively looks for methods in a nested class's superclass hierarchy before looking for methods in an enclosing class and its superclass hierarchy. See §6.5.7.1 for an example.
至于为什么 OpenJDK Java 7 接受你的测试类......如果这确实是真的,我会称之为编译器错误。但这是 Java 7 的一个普遍错误,而不是 OpenJDK 特有的错误。对于同一版本的 Oracle 和 OpenJDK 版本,javac
代码库(据我所知)是相同的。
有趣的是,我有一份 Oracle Java 6 的副本,该版本的 javac
也将此称为编译错误。
$ /usr/java/jdk1.6.0_45/bin/javac InnerClass.java
InnerClass.java:10: cannot find symbol
symbol: method toString(java.lang.String)
System.out.println(toString("test"));
^
1 error
所以...也许...您应该重新运行 OpenJDK Java 7 测试,并确保您正在编译相同的源代码!
关于javac - OpenJDK和Oracle中匿名内部类直接调用外部类实例方法有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47725077/
我是一名优秀的程序员,十分优秀!