如何在lambda内部使用构造函数注入类的实例变量

时间:2019-02-22 09:53:48

标签: spring lambda java-8 immutability constructor-injection

Customer类使用构造函数注入(建议通过字段注入),但是实例字段在lambda内部不可用。

@Component
public class Customer {

  private final Account account;

  @Autowired
  public Customer(final Account account) {
    this.account = account;
  }

  // Works perfectly fine
  Callable propCallable = new Callable<String>(){
    @Override
    public String call() throws Exception {
        return account.accountId();
    }
  };

  //Shows warning : Variable account might not have been initialized
  Callable lambdaCallable = () -> {
    return account.accountId();
  };
}

我只是想知道是否有更好的方法在lambda中使用实例变量,而不是匿名类?

注意:我希望保留最终帐户。

预先感谢

2 个答案:

答案 0 :(得分:2)

匿名类和lambda之间有一些differences。在这种情况下,主要的是:

  

编译–匿名编译为类,而lambda是invokedynamic指令

现在有关编译器错误。通过Java order of initialization rules,您的lambda初始化发生在构造函数中的“帐户”分配之前。不确定,但是由于编译差异,匿名类没有这种错误。

因此,您可以从方法返回lambda,或将“ lambdaCallable”初始化移至构造函数。

public class DemoApplication {

    public class Customer {

        private final Account account;

        public Customer(final Account account) {
            this.account = account;
        }

        // Works perfectly fine
        Callable propCallable = new Callable<String>(){
            @Override
            public String call() throws Exception {
                return account.accountId();
            }
        };

        Callable getCallable() {
            return account::getId;
        }

//        Callable lambdaCallable = () -> {
//            return account.accountId();
//        };
    }
}

答案 1 :(得分:1)

lambdaCallable定义移至构造函数内部:

private final Callable<Long> lambdaCallable;
@Autowired
public Customer(final Novel account) {
   this.account = account;
   lambdaCallable = account::getId;
}