我正在解决一些练习,以便更好地理解java中的内部类是如何工作的。我发现了一个很有趣的练习。该练习的条件是使printname()
打印“sout”而不是“main”,且更改最少。有它的代码:
public class Solution {
private String name;
Solution(String name) {
this.name = name;
}
private String getName() {
return name;
}
private void sout() {
new Solution("sout") {
void printName() {
System.out.println(getName());
// the line above is an equivalent to:
// System.out.println(Solution.this.getName);
}
}.printName();
}
public static void main(String[] args) {
new Solution("main").sout();
}
}
我们有一个有趣的情况--这两个类有is-A和HAES-A联系。这意味着匿名内部类扩展了外部类,而且内部类的对象也引用了外部类的对象。如果您运行上面的代码,“main”将被打印出来。子级不能通过继承调用父级的getname()
。但是作为内部类的子类使用对父类(外部类)的引用来访问方法。
解决此任务的最简单方法是将getname()
的访问修饰符从private
更改为其他任何内容。因此子级能够通过继承使用getname()
,并且由于后期绑定,将打印“sout”。
private void sout() {
new Solution("sout") {
void printName() {
System.out.println(super.getName());
}
}.printName();
}
谢谢你的尝试)
Java语言规范(JLS)在编译器解析方法调用表达式的上下文中规定
如果表单为super。[TypeArguments]identifier
,则要搜索的类是其声明包含方法调用的类的超类。
在本例中,其声明包含方法调用的类是匿名solution
子类,其超类是solution
。在确定将使用哪个实例调用方法的上下文中,JLS接着说
new Solution("sout") {
void printName() {
System.out.println(getName());
}
}.printName();
然后,JLS声明
否则,让t
是方法作为成员的封闭类型声明,让n
是整数,这样t
是该类的第n个词法封闭类型声明,该类的声明立即包含方法调用。目标引用是this
的第n个词法封闭实例。
同样,T
是solution
,这是自其声明立即包含方法调用的类是匿名solution
子类以来的第一个词法封闭类型。此
是匿名解决方案
子类实例。因此,目标引用是这个
的第一个词法封闭实例。解决方案
实例,其名称
字段是用值“main”
初始化的。这就是为什么原始代码打印“main”
。
null null 产品版本:NetBeans IDE 7.3.1(构建201306052037)Java:1.7.0_25;Java HotSpot(TM)64位服务器VM 23.25-B01运行时:Java(TM)SE运行时环境1.7.0_25-B17系统:Windows 7 Version6.1在AMD64上运行;CP1252;en_US(nb) 清理、构建和重新启动Netbeans并没有解
我通过在public static void main()方法中实现接口I创建了匿名类。因此,Java8对于抽象方法test()的实现是从C类的imple()方法中提供的。 因此,在public static void main()方法printing_interface.getclass(),我得到了 但最终它打印的是package_path.C(告诉我C是类名)。这怎么可能?不应该再次打印pa
问题内容: 如果我有以下课程: 我显然可以实例化该对象,并且我知道必须进行某种子类化,因为我可以覆盖Hooray方法,但是如果有子类化,为什么我不能在匿名类内创建一个新方法? 返回语法错误 问题答案: 您可以创建方法,方法没有任何问题(除了它的前面有一个大写字母之外)。问题在于,在匿名类之外,Boo方法不可用(它没有作为类API的一部分公开)。 这与实现接口的任何类都是相同的…如果该类具有不属于接
问题内容: 在Java 7和更高版本中,菱形通常可以像这样毫无问题地用于推断类型: 但是,它不能用于这样的匿名内部类: 为什么是这样?从逻辑上讲,在这种情况下,我绝对可以将类型推断为。做出该决定的逻辑上的理由是,实际上不能在匿名内部类上推断类型,还是出于其他原因而将其省略了? 问题答案: 在JSR-334中: 不支持将Diamond与匿名内部类一起使用,因为这样做通常需要扩展类文件签名属性以表示不
问题内容: 在进行一些基本的lambda练习时,一个看似完全相同的匿名内部类的输出给我的输出与lambda不同。 场景1 输出 2 和 2 。这里没有新内容。 但是当我这样做时: 场景2 输出 2 和 3 问题:两个输出不应该相同吗? 我想念什么吗? 为了完整起见: 方案3 输出 3 和 3 。这里也没有什么新鲜的。 更新:仍从1.8.0-b132获得相同的输出 更新#2:错误报告: https
问题内容: 就在今天,我需要一种在不同对象之间传递函数的方法。我很快了解到您不能直接在Java中做到这一点,但是您可以传递一个wht实例,该实例显然被称为“匿名内部类”,如下所示: 定义类: 使其成为一个实例: 并称之为: 很简单。但是我不明白的是为什么它被称为“匿名”。我不只是给它起名字MyCallback吗?命名的东西不能匿名,对吗?请避免对这个术语感到困惑。 问题答案: 不,您说的是MyCa