Kotlin(十二) 定义静态方法

静态方法在某些编程语言里面又叫作类方法,指的就是那种不需要创建实例就能调用的方法,所有主流的编程语言都会支持静态方法这个特性。

在Java中定义一个静态方法非常简单,只需要在方法上声明一个static关键字就可以了,如下所示:

java 复制代码
public class Util {

    public static void xxxx() {
        System.out.println("xxxx");
    }

}

这是一个非常简单的工具类,上述代码中的xxxx方法就是一个静态方法。调用静态方法并不需要创建类的实例,而是可以直接以Util.xxxx()这种写法来调用。因而静态方法非常适合用于编写一些工具类的功能,因为工具类通常没有创建实例的必要,基本是全局通用的。

但是和绝大多数主流编程语言不同的是,Kotlin却极度弱化了静态方法这个概念,想要在Kotlin中定义一个静态方法反倒不是一件容易的事。

那么Kotlin为什么要这样设计呢?因为Kotlin提供了比静态方法更好用的语法特性,并且我们在上一节中已经学习过了,那就是单例类。

像工具类这种功能,在Kotlin中就非常推荐使用单例类的方式来实现,比如上述的Util工具类,如果使用Kotlin来实现的话就可以这样写:

Kotlin 复制代码
object Util {

    fun xxxx() {
        println("xxxx")
    }

}

虽然这里的xxxx()方法并不是静态方法,但是我们仍然可以使用Util.xxxx()的方式来调用,这就是单例类所带来的便利性。

不过,使用单例类的写法会将整个类中的所有方法全部变成类似于静态方法的调用方式,而如果我们只是希望让类中的某一个方法变成静态方法的调用方式该怎么办呢?这个时候就可以使用刚刚在最佳实践环节用到的companion object了,示例如下:

Kotlin 复制代码
class Util {

    fun xxxx1() {
        println("xxxx1")
    }

    companion object {

        fun xxxx2() {
            println("xxxx2")
        }

    }

}

这里首先我们将Util从单例类改成了一个普通类,然后在类中直接定义了一个xxxx()方法,又在companion object中定义了一个xxxx2()方法。现在这两个方法就有了本质的区别,因为xxxx()方法是一定要先创建Util类的实例才能调用的,而xxxx2()方法可以直接使用Util.xxxx2()的方式调用。

不过,xxxx2()方法其实也并不是静态方法,companion object这个关键字实际上会在Util类的内部创建一个伴生类,而xxxx2()方法就是定义在这个伴生类里面的实例方法。只是Kotlin会保证Util类始终只会存在一个伴生类对象,因此调用Util.xxxx2()方法实际上就是调用了Util类中伴生对象的xxxx2()方法。

由此可以看出,Kotlin确实没有直接定义静态方法的关键字,但是提供了一些语法特性来支持类似于静态方法调用的写法,这些语法特性基本可以满足我们平时的开发需求了。

然而如果你确确实实需要定义真正的静态方法, Kotlin仍然提供了两种实现方式:注解和顶层方法。下面我们来逐个学习一下。

先来看注解,前面使用的单例类和companion object都只是在语法的形式上模仿了静态方法的调用方式,实际上它们都不是真正的静态方法。因此如果你在Java代码中以静态方法的形式去调用的话,你会发现这些方法并不存在。而如果我们给单例类或companion object中的方法加上@JvmStatic注解,那么Kotlin编译器就会将这些方法编译成真正的静态方法,如下所示:

Kotlin 复制代码
class Util {

    fun xxxx1() {
        println("xxxx1")
    }

    companion object {

        @JvmStatic
        fun xxxx2() {
            println("xxxx2")
        }

    }

}

注意,@JvmStatic注解只能加在单例类或companion object中的方法上,如果你尝试加在一个普通方法上,会直接提示语法错误。

由于xxxx2()方法已经成为了真正的静态方法,那么现在不管是在Kotlin中还是在Java中,都可以使用Util.xxxx2()的写法来调用了。

再来看顶层方法,顶层方法指的是那些没有定义在任何类中的方法,比如我们在上一节中编写的main()方法。Kotlin编译器会将所有的顶层方法全部编译成静态方法,因此只要你定义了一个顶层方法,那么它就一定是静态方法。

想要定义一个顶层方法,首先需要创建一个Kotlin文件。对着任意包名右击 → New → Kotlin File/Class,在弹出的对话框中输入文件名即可。注意创建类型要选择File。

点击"OK"完成创建,这样刚刚的包名路径下就会出现一个Helper.kt文件。现在我们在这个文件中定义的任何方法都会是顶层方法,比如这里我就定义一个doSomething()方法吧,如下所示:

Kotlin 复制代码
fun doSomething() {
    println("do something")
}

刚才已经讲过了,Kotlin编译器会将所有的顶层方法全部编译成静态方法,那么我们要怎么调用这个doSomething()方法呢?

如果是在Kotlin代码中调用的话,那就很简单了,所有的顶层方法都可以在任何位置被直接调用,不用管包名路径,也不用创建实例,直接键入doSomething()即可,如下所示:

Kotlin 复制代码
fun main(){

    doSomething()

}
相关推荐
Scott9999HH43 分钟前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
码智社2 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海2 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖3 小时前
JDK 26 新特性详解
java·开发语言
马优晨3 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区5 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大6 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai6 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
এ慕ོ冬℘゜6 小时前
前端基础:什么是时间戳?JS获取时间戳三种方法与实战用途
开发语言·前端·javascript
执明wa6 小时前
LayoutInflater详解: XML是如何变成View的?
android·xml·开发语言·android studio