Java Lambda无法访问内部作用域?是否有语法糖替代匿名内部类?
问题分析与解决方案
你的代码报错是因为lambda表达式() -> getValue()的作用域属于类c,编译器会尝试在c中查找getValue()方法,而不是你期望的a<T>实例的方法——lambda本质是实现Callable<T>的逻辑,它无法直接引用将要创建的a<T>实例的成员。
有没有语法糖能绕过这个限制?
没有这样的语法糖。lambda的设计定位是无状态的函数实现,它内部无法获取到自身将要生成的接口实例的引用,所以没办法直接在lambda里调用该实例的getValue()方法。
可行的解决办法
1. 调整类设计(推荐)
如果你的需求是让a<T>实例的call()方法返回自身的getValue(),可以给concreteA添加一个无参构造方法,在内部直接绑定这个逻辑,不用外部传入Callable:
static class concreteA<T> implements a<T> { private final Callable<T> delegate; // 自定义call逻辑的构造方法 concreteA(Callable<T> delegate) { this.delegate = delegate; } // 默认call返回getValue()的构造方法 concreteA() { // 这里可以安全调用自身的getValue() this.delegate = () -> (T) Integer.valueOf(getValue()); } @Override public int getValue() { return 99999; } @Override public T call() throws Exception { return this.delegate.call(); } }
然后在接口a中添加对应的静态工厂方法:
static <T extends Integer> a<T> ofDefault() { return new concreteA<>(); }
最后在main中直接调用:
public static void main(String[] args) throws Exception { System.out.println(a.ofDefault()); }
2. 使用匿名内部类(直接解决原写法问题)
如果你坚持要通过a.of()传入逻辑,只能用匿名内部类实现Callable,但注意:这种方式无法引用到同一个concreteA实例的getValue()(因为Callable是在concreteA构造前传入的,无法获取其引用)。如果你的需求是复用concreteA的getValue()实现,可以创建一个临时实例来调用:
public static void main(String[] args) throws Exception { // 注意:这里调用的是另一个concreteA实例的getValue() System.out.println(a.of(() -> new concreteA<Void>(null).getValue())); }
如果需要调用同一个实例的getValue(),则必须直接实现a<T>接口,绕开a.of():
public static void main(String[] args) throws Exception { System.out.println(new a<Integer>() { @Override public Integer call() throws Exception { return getValue(); // 这里的getValue()就是当前实例的方法 } @Override public int getValue() { return 99999; // 复用concreteA的实现可以写成return new concreteA<>(null).getValue(); } }); }
内容的提问来源于stack exchange,提问作者nsayer
相关产品推荐
相关产品推荐

