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

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

情况1

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

情况2

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

情况3

 fun doSomething() {} 

字节码结果

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

我的问题是:

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

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

  • 提供封装声明方法,伴随对象和对象的有意义的例子。

语境。 我一直在Kotlin编码,我觉得它很棒。 但有时我需要做出决定:例如,在java中,我将声明为静态最终的一个沉重的不变属性,但在Kotlin中,我发现很难“找到一个等价的”。

我会建议开发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"))); } 

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

如果您想将方法作为Java代码的静态方法公开,您可以使用@JvmStatic批注@JvmStatic批注。

如果一个函数不需要一个类的实例,那么这是你的设计决定把它放在哪里。 如果包级别是包特定的,则使用包级别,如果类包级紧密关联到类(例如包中的其他类具有类似的功能),则使用类级联。

请注意, 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)