14

我在 Kotlin 中编写了这个方法并分析了字节码:

情况一

class A {
    object b {
        fun doSomething() {}
    }
}

情况2

class A {
    companion object b {
        fun doSomething() {}
    }
}

情况 3

fun doSomething() {}

字节码结果

  • 情况1:班级Test$asbpublic final doSomething()I
  • 情况2:班级Test$Companionpublic final doSomething()I
  • 情况3:班级TestKtpublic final static doSomething()I

我的问题是:

  • 我有一个枚举类,我想返回一个给定枚举变量的枚举实例,例如 findById (enum(id, color))。我该怎么做?伴侣对象?目的?

  • 似乎拥有真正静态方法的唯一方法是在包级别,没有类声明。但这变得有点过于全球化了。有什么方法可以通过: 访问它ClassName.staticMethod, staticMethod 真的是静态的。

  • 提供包声明方法、伴生对象和对象的有意义的示例。

语境。我一直在使用 Kotlin 进行编码,我觉得它很棒。但有时我需要做出决定:例如,在 java 中我会声明为 static final 的重不可变属性,但在 Kotlin 中我发现很难“找到等价物”。

4

3 回答 3

10

如果您有一个执行与类密切相关的操作但不需要类实例的函数,例如您的findById示例,则应将其放在类的伴生对象中。

如果要将方法作为静态方法公开给 Java 代码,可以使用注解对其进行@JvmStatic注解。

于 2016-06-24T21:37:31.213 回答
7

如果一个函数不需要类的实例,那么将它放在哪里是您的设计决定。如果它是特定于包的,则使用包级别,如果它与类密切相关,则使用类伴侣(例如,包中的其他类具有类似的功能)。

请注意,它enum有几个内置属性和模式:

enum class Colour(val value: Int) {
    black(100), red(200), green(300)
}

fun colourById(id: Int) = Colour.values[id]
fun colourByValue(value: Int) = Colour.values.first {it.value == value}
fun colourByName(name: String) = Colour.valueOf(name)
于 2016-06-25T11:58:25.940 回答
2

我建议开发voddan 答案

enum class Color {

    RED,
    BLUE,
    GREEN;


    companion object Utils {
        fun findById(color: Color): Color {
            return color;
        }
    }
}

并进行测试

@Test
fun testColor() {
    println(Color.Utils.findById(Color.valueOf("RED")));
}
于 2016-06-26T08:46:21.310 回答