繁体   English   中英

Java私有静态最终字段和匿名内部类与Kotlin const val和对象表达式/声明

[英]Java private static final field and anonymous inner classes vs. Kotlin const val and object expressions/declarations

假设我有一个Kotlin界面:

interface Dog {
    fun walk()
}

我想创建一个带有此类修改的此类Kotlin对象 ,如下所示:

val poodle : Dog = object : Dog {

    override fun walk() {
        ...
    }
}

但是,我也想向此对象添加一个等效于Java中的私有static final字段的东西,就像这样( 这是Java中的一个有效示例 ):

Dog poodle = new Dog() {

    private static final String POODLE_FASHION = ...

    @Override
    public walk() {
        ...
    }
}

我读到私有常量相当于Kotlin中的这个常量。 我尝试执行以下操作(这是Kotlin中无法正常工作的示例)

val poodle : Dog = object : Dog {

    private const val POODLE_FASHION = ...

    override fun walk() {
        ...
    }
}

当我这样做时,我在Android Studio中遇到以下错误: 仅在顶层或对象中允许使用const'val'

有人可以解释为什么Java版本有效,但Kotlin版本无效吗? 如何为Kotlin做到这一点(我已经尝试了伴随对象,但收到了错误修饰符'companion'在'local class'中不适用 )? 请注意,我不想执行以下操作,因为我希望POODLE_FASHIONval poodle因为我还要创建其他经过稍微修改的Dog对象( val pugval chihuahua等):

private const val POODLE_FASHION = ...

val poodle : Dog = object : Dog {

    override fun walk() {
        ...
    }
}

谢谢!

val poodle : Dog = object : Dog {

    private const val POODLE_FASHION = ...

    override fun walk() {
        ...
    }
}

在此示例中,实际上完全没有理由POODLE_FASHION必须为静态或const。 它可以只是一个普通的val ,它不会花费您任何额外的费用。

也就是说,听起来您应该拥有一个Poodle类,而不是一个对象。

注意对象表达式和对象声明之间的区别。

  • val poodle = object: Dog { ... }是一个对象表达式 它创建一个匿名对象。 这等效于用Java编写Dog poodle = new Dog() { ... }
  • object Poodle: Dog { ... }是一个对象声明 它创建一个单例对象,并且大致等效于创建一个Java类,该类仅限于只有一个实例。

Kotlin文档指出const val属性必须是“顶级,或者是对象声明或伴随对象的成员”。 https://kotlinlang.org/docs/reference/properties.html#compile-time-constants )。 它们在对象表达式中无效。

以下对象声明应该可以正常工作:

object Poodle : Dog {
    private const val POODLE_FASHION = ...

    override fun walk() {
        ...
    }
}

区别的一个重要原因是对象表达式未声明新类型(尽管用Java来讲,它确实会导致一个匿名类)。

  • val poodle = object: Dog { ... }创建一个Dog类型的变量。 没有像Poodle这样的类型。
  • object: Poodle: Dog { ... }创建一个Poodle类型的对象。 这是一种新类型,是Dog的子类型。

这种差异很重要,因为在Kotlin中, const val属性始终属于类型。 MyClass.MY_CONST_VAL是有效的,但以MyClass().MY_CONST_VAL身份访问是错误的,因此无法使用。 结果,匿名对象上的const val属性将始终对该对象有效。

我看不到技术上的原因,为什么不可能在匿名对象上允许const val属性(Java内部类中允许使用static final编译时常量字段),但是它们的用途将受到严格限制,并且它实际上是不是Kotlin语言规范的一部分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM