Kotlin对象与伴随对象与包范围方法

joh*_*crq 12 static kotlin companion-object

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

情况1

class A {
    object b {
        fun doSomething() {}
    }
}
Run Code Online (Sandbox Code Playgroud)

情况2

class A {
    companion object b {
        fun doSomething() {}
    }
}
Run Code Online (Sandbox Code Playgroud)

情况3

fun doSomething() {}
Run Code Online (Sandbox Code Playgroud)

字节码结果

  • 情况1:上课Test$asb,public final doSomething()I
  • 情况2:上课Test$Companion,public final doSomething()I
  • 情况3:上课TestKt,public final static doSomething()I

我的问题是:

  • 我有一个枚举类,我想在给定枚举变量的情况下返回一个枚举实例,例如findById (enum(id, color)).我该怎么办?伴侣对象?宾语?

  • 似乎有一个真正的静态方法的唯一方法是在包级别,没有类声明.但这有点过于全球化.有没有办法通过以下方式访问它:ClassName.staticMethod,staticMethod是非常静态的.

  • 提供有意义的包声明方法,伴随对象和对象的示例.

语境.我一直在Kotlin编码,我发现它很棒.但有时我需要做出决定:例如,一个沉重的不可变属性在java中我会声明为静态final,但在Kotlin中我发现很难"找到一个等价物".

yol*_*ole 9

如果你有一个函数执行一些与类紧密相关的操作但不需要类实例(例如你的findById例子),你应该把它放在类的伴随对象中.

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


vod*_*dan 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)
Run Code Online (Sandbox Code Playgroud)


小智 2

我建议开发voddan 答案

enum class Color {

    RED,
    BLUE,
    GREEN;


    companion object Utils {
        fun findById(color: Color): Color {
            return color;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并进行测试

@Test
fun testColor() {
    println(Color.Utils.findById(Color.valueOf("RED")));
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么不直接从“Color”类调用?`println(Color.findById(Color.valueOf("RED")));` (5认同)