代码之家  ›  专栏  ›  技术社区  ›  user1578872

Lambda操作符()->是如何工作的?

  •  2
  • user1578872  · 技术社区  · 6 年前

    我想了解下面的代码是如何工作的。

    @Bean
    public StateHandlerDef handler() {
        return () -> StateOne.class;
    }
    
    @Named
    @Scope("prototype")
    public class StateOne extends AbstractStateActorActor<StatObject> {
    
        @Inject
        public StateOne(final Props prop, final StatRegistry statRegistry) {
            super("test", transformationConfig, GenericStateObject.class, statRegistry);
        }
    }
    
    @FunctionalInterface
    public interface StateHandlerDef {
        Class<? extends AbstractUntypedActor> getHandlerClass();
    }
    

    这是工作代码。

    我想了解,bean的创建是如何在这里工作的。

    @Bean
    public StateHandlerDef handler() {
        return () -> StateOne.class;
    }
    

    StateOne类有一个构造函数。但是,这会在不传递构造函数参数的情况下创建bean。此外,返回类型是一个函数接口,它不是由实际的状态类实现的,也不确定它是如何工作的。这是基于Akka演员模型的。

    AbstractStateActorActor extends AbstractUntypedActor
    

    这里,我想以编程方式设置bean名称,而不是通过注释进行设置。

    Caused by: akka.actor.ActorInitializationException: You cannot create an instance of [com.test.Test] explicitly using the constructor (new). You have to use one of the 'actorOf' factory methods to create a new actor. See the documentation.
        at akka.actor.ActorInitializationException$.apply(Actor.scala:181) ~[akka-actor_2.11-2.4.19.jar:na]
    

    有什么帮助吗?

    3 回复  |  直到 6 年前
        1
  •  2
  •   Mustafa    6 年前

    要理解这一点,就要这样想。您试图扩展的库(在本例中为akka)需要知道将要处理状态的类。为此,它将获得类型为的实例(bean) StateHandlerDef

    @Bean
    public StateHandlerDef handler() {
        return () -> StateOne.class;
    }
    

    这相当于:

    @Bean
    public StateHandlerDef handler() {
        return new StateHanderDefImpl();
    }
    

    图书馆会用这个来获取 StateOne.class ,它将为其查找bean并从依赖项注入框架中获取它。该bean定义如下:

    @Named
    @Scope("prototype")
    public class StateOne extends AbstractStateActorActor<StatObject> {
    
        @Inject
        public StateOne(final Props prop, final StatRegistry statRegistry) {
            super("test", transformationConfig, GenericStateObject.class, statRegistry);
        }
    }
    

    DI框架将通过在其构造函数中注入所需的依赖项,从该类创建bean。

        2
  •  1
  •   Chandra Shekhar Paatni    6 年前

    @FunctionalInterface
    interface ClassHandleDef {
      Class<? extends Object> getHandlerClass();
    }
    

    现在,我们正在创建接口ClassHandleDef的匿名类,并提供gethandlerClass方法的主体。

    new ClassHandleDef() {
            @Override
            public Class<? extends Object> getHandlerClass() {
                return String.class;
            }
        };
    

    现在我们正在删除不需要的额外代码。根据lambda表达式,删除所有额外代码,并提供参数(如果存在)以及lambda运算符的方法体定义。

    () -> String.class;
    
    • 若有单行方法定义,那个么就不需要显式地编写return语句。
    • a->a*2;

    我希望你能理解lambda表达式的工作流程。感谢您抽出时间阅读这篇文章。

        3
  •  1
  •   buræquete Naveen Kocherla    6 年前

    那里的功能接口 StateHandlerDef 在某种程度上表示getter函数 getHandlerClass() 在其类定义中使用lambda定义定义的。声明如下:;

    @Bean
    public StateHandlerDef handler() {
        return () -> StateOne.class; // a supplier, no input, returns value (getter)
    }
    

    我们基本上是在实施 通过定义 getHandlerClass() 方法这就是lambda的返回值与getter方法相同的原因, StateOne 是一种 Class<? extends AbstractUntypedActor>

    因此,在某种程度上,我们创建的bean如下所示:;

    public interface StateHandlerDef {
        Class<? extends AbstractUntypedActor> getHandlerClass();
    }
    
    public class StateHandlerDefImpl implements StateHandlerDef {
    
        // explicit way of writing lambda "() -> StateOne.class"
        Class<? extends AbstractUntypedActor> getHandlerClass() {
            return StateOne.class;
        }
    }
    
    @Bean
    public StateHandlerDef handler() {
        return new StateHandlerDefImpl();  // then we use the getter thru this bean.
    }
    

    具有 @FunctionalInterface 我们可以跳过上面给出的接口实现,只需使用传递的lambda(这是一个 Supplier

    @Autowire
    private StateHandlerDef handler;
    
    public .. someLogic() {
        ...
        handler.getHandlerClass();  // will trigger the lambda, returning `StateOne.class`
        ...
    }
    

    您可以通过更改bean的创建方法的名称来更改bean的名称。 @Bean handler() 将生成名为的bean handler .

    我尽量简化,希望可以理解,否则请检查 this