JDK8创建内部类实例报错:No enclosing instance of type Person is accessible
问题原因与解决方案
为什么会报错?
CheckPersonEligibleForSelectiveService是非静态内部类(未加static修饰),这类内部类的实例必须绑定到一个外部类Person的实例上——它默认持有外部类实例的引用,理论上可以访问外部类所有非静态成员。
而main是静态方法,静态方法属于类本身,不依附任何实例。在静态方法里直接执行new CheckPersonEligibleForSelectiveService()时,编译器找不到可绑定的Person实例,因此抛出编译错误。
你用person0.new CheckPersonEligibleForSelectiveService()时,是显式指定用person0这个外部类实例绑定内部类实例,满足了非静态内部类的创建要求,所以代码能正常运行。
最优解决方案
你的代码里,CheckPersonEligibleForSelectiveService根本没用到外部类Person的非静态成员,完全没必要做成非静态内部类。给它加上static修饰改成静态内部类,就能在静态方法里直接创建实例:
// 修改为静态内部类 static class CheckPersonEligibleForSelectiveService implements CheckPerson { public boolean test(Person p) { return p.gender == Person.Sex.MALE && p.getAge() >= 18 && p.getAge() <= 25; } }
改完后,原来的printPersons(roster, new CheckPersonEligibleForSelectiveService())就能正常编译运行。
贴合Lambda教程的进阶写法
既然你在学习Lambda表达式,这个内部类完全可以用Lambda替代,代码更简洁,也符合教程的演进方向:
// 用Lambda表达式直接替代内部类实例 printPersons(roster, p -> p.gender == Person.Sex.MALE && p.getAge() >= 18 && p.getAge() <= 25 );
这样无需编写内部类,直接把判断逻辑以Lambda形式传入,这也是Java 8引入Lambda的核心应用场景之一。
内容的提问来源于stack exchange,提问作者bfin
相关产品推荐
相关产品推荐

