Kotlin中的Util类(最佳方法)?

7
我正在使用Kotlin编写Util类,并采用不同的方法。我正在尝试一种既适用于Kotlin也适用于Java的最佳调用方式。
现在我已经创建了许多类型的Util,但我很困惑应该选择哪个并且最重要的是为什么?我正在寻找考虑堆、内存和性能的最佳方法。
我的问题可能对你们来说看起来很愚蠢,但我自己陷入了迷宫无法得出解决方案。
这是我的游乐场。
我创建了5个Kotlin文件,在其中放置了foo()方法,并尝试通过Kotlin和Java进行调用。
引用Bar.kt类的调用如下:
class Bar {
    fun bazz() {
        UtilClass.instance.foo()
        UtilClassObject.UtilClassObject.foo()
        UtilCompanionObject.foo()
        UtilFileObject.foo()
        foo() // from UtilFile
    }
}

调用类 Qux.java
public class Qux {
    public void bazz() {
        UtilClass.Companion.getInstance().foo();
        UtilClassObject.UtilClassObject.INSTANCE.foo();
        UtilFileKt.foo();
        UtilFileObject.INSTANCE.foo();
        UtilCompanionObject.Companion.foo();
    }
}

这里是让我感到困惑、无法选择最佳选项的迷宫

UtilClass.kt

class UtilClass {
    fun foo() { ... }

    companion object {
        val instance = UtilClass()
    }
}

UtilClassObject.kt

class UtilClassObject {
    object UtilClassObject {
        fun foo() { ... }
    }
}

UtilCompanionObject.kt

class UtilCompanionObject {
    companion object {
        fun foo() { ... }
    }
}

UtilFile.kt

fun foo(){ ... }

UtilFileObject.kt

object UtilFileObject {
    fun foo() { ... }
}

可能需要一些时间来回答我的问题并且解释得很好。所以我非常感谢您的努力。


你能展示一下你更喜欢如何称呼它,而不是给出所有可能的排列方式以及你使用该方法时遇到的错误吗? - Jayson Minard
我基本上是Java开发人员,所以我习惯于调用Util.getInstance().foo()或者有时使用静态方法的Util.foo()。现在我只想知道这些中最好的方法。我很好奇所有上述类型之间的区别,考虑到堆内存,哪种方法最好。 - Khemraj Sharma
@JaysonMinard 是的,我发现像我在 UtilFile.kt 中提到的那样创建全局方法最容易。但是将成千上万的方法置于全局范围内是否是好的做法呢? - Khemraj Sharma
下面所回答的方法是Java/Kotlin中实现调用静态/伴生方法的常见方式。 - Jayson Minard
1
@Khemraj,你声明实用方法的方式极不可能对应用程序的性能产生任何可测量的影响。如果JIT运行后不同声明之间仍然存在性能差异,那么这种差异将以纳秒为单位进行测量。另一方面,通过正确选择算法和数据结构可以获得的差异是以毫秒和秒为单位进行测量的。 - yole
1个回答

13
所有选项都在Kotlin参考页面中提供,用于Kotlin和Java之间的互操作:https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html 如果您想从Java调用类MyUtil上的某些内容,并且不需要实例,例如MyUtil.foo(),那么您只需执行以下两个选项之一即可:
// smallest byte code, 
//   static invocation of foo() from Kotlin side,
//   also static call from Java to foo()
object MyUtil {
    @JvmStatic fun foo() { ... }
}

或者

// creates two classes,
//    static lookup of companion followed by virtual call on that instance to foo() from Kotlin, 
//    Java is a static call to foo()
class MyUtil {
    companion object {
        @JvmStatic fun foo() { ... }
    }
}

你可以在Kotlin中使用相同的方式调用MyUtil.foo(),这是一种将Kotlin方法设置为静态的模式。
两个示例在Java中看起来相同,因为它们都是直接对静态方法进行静态调用。从Kotlin中,第一个示例也是静态调用,第二个示例首先查找伴生对象的实例,然后对该方法进行虚拟调用。第二个示例创建了两个类,而另一个只创建了一个类。
你提出的其他选项不仅语法丑陋,而且效率也不高。基于最小字节码、最少类和最快性能,请选择第一个示例,即只有1个类和所有静态调用。

更新答案为两个等效的答案,根据此处所询问的内容,两者都没有更好的。 - Jayson Minard
先生,我同意您的答案,但我不是在征求意见,我想知道它们在运行时的实现和流程之间的区别,这样我就可以为所有未来的项目选择一个。我保证我选择的方式是性能最佳的方法。语法实际上并不重要,性能才是关键。 - Khemraj Sharma
首选项是一个类而不是两个,这样从 Kotlin 方面的调用中减少了工作量,Java 方面则相同。请参见我在它们上面添加的注释。 - Jayson Minard
1
我根据您的评论和澄清更新了答案。 - Jayson Minard
5
在 Kotlin 中,实际推荐的方法既不是你所建议的任何一种,而是使用顶层函数。这样做没有额外开销,在 Kotlin 中最容易使用,且需要的代码最少。 - yole
显示剩余9条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接