我可以在Kotlin中使用Dagger 2的场注入吗? [英] Can I use Dagger 2's field injection in Kotlin?

查看:197
本文介绍了我可以在Kotlin中使用Dagger 2的场注入吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发布了一个问题( Dagger 2没有生成组件类(Android,Kotlin)),经过一些实验,看来问题可能出在Kotlin隐藏该字段.

I posted a question (Dagger 2 does not generate the component class (Android, Kotlin)), and after some experiments, it seems that the problem might be due to that Kotlin hides the field.

class CoffeeShop {
    @Inject
    var theCoffee: Coffee? = null
}

错误消息是

:app:kaptDebugKotline: ...\CoffeeShop.java:7:
error: Dagger does not support injection into private fields
e:     private ....Coffee theCoffee;

theCoffee在我的源代码中不是私有的.但我认为Kotlin可能正在翻译

theCoffee was not private in my source code. But I think Kotlin may be translating

class CoffeeShop {
    @Inject
    var theCoffee: Coffee? = null
}

转换为的Java代码

class CoffeeShop {
    @Inject
    private Coffee theCoffee = null;
    public Coffee getTheCoffee();
    public void setTheCoffee();
}

我可以在Kotlin中使用场注入吗?

Can I use field injection in Kotlin?

推荐答案

我认为Kotlin可能正在将[...]转换为[...]的Java代码

I think Kotlin may be translating [...] into Java code of [...]

您是正确的,这就是会发生的事情.

And you would be correct, that's exactly what happens.

在科特林,您通常不会写

Typically in Kotlin you wouldn't write

@Inject var coffee: Coffee? = null

因为要使用咖啡,它永远不会为空.换句话说,您将始终在访问对象的字段之前注入对象.这使得运算符!!多余,而?则不必要. Kotlin具有lateinit属性修饰符来表达这一点.

because when you're going to access coffee, it will never be null. In other words you will always inject the object before accessing it's fields. That makes the operators !! redundant and ? unnecessary. Kotlin has lateinit property modifier to express this.

@Inject lateinit var coffee: Coffee

使用lateinit时,生成的字段与其getter和setter(在本例中为public)具有相同的可见性.这使得它可以与Dagger一起使用.

When you use lateinit the generated field has the same visibility as its getter and setter, in this case public. This makes it work with Dagger.

您可以通过查看生成的Kotlin字节码来查看结果.

You can see the result by viewing generated Kotlin bytecode.

主菜单>工具> Kotlin>显示Kotlin字节码

Main menu > Tools > Kotlin > Show Kotlin Bytecode

但是,更好的方法是注入类构造函数:

However, even better approach would be injecting the class constructor:

class CoffeeShop @Inject constructor(val coffee: Coffee) {
    //...
}

在这种情况下,coffee不是var,因此无法重新分配.

In this case coffee is not var and can't be reassigned.

在通过框架为您创建实例时,不能选择注入构造函数,Android活动就是一个很好的例子.

Injecting constructor is not an option when the instance is created for you by a framework, Android activity is a good example.

注意:使用限定符时,必须在其上指定field注释目标:

Note: When using qualifiers you have to specify field annotation target on them:

@Inject @field:Named("Arabica") @field:Arabica
lateinit var coffee: Coffee

编辑:使用

You don't need to add the field target when using Dagger 2.25 or newer.

我可以在Kotlin中使用场注入吗?

Can I use field injection in Kotlin?

是的,可以.如上所述,场注入实际上应用于lateinit属性.

Yes you can. As explained above, field injection is actually applied for lateinit properties.

但是您可能对在Kotlin中没有getter/setter的情况下生成和注入字段感兴趣.

But you were probably interested in generating and injecting fields without getter/setter in Kotlin.

@JvmField @Inject
var coffee: Coffee? = null

这篇关于我可以在Kotlin中使用Dagger 2的场注入吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆