Kotlin系列之顶层函数和属性

今天一起来看看Kotlin中的顶层函数和属性。

遇到的问题

我们都知道,Java中,所有的代码都是依托于类而存在,我们所谓的函数作为类的方法,我们所谓的属性作为类的属性。但是在有些情况下,我们发现有些方法可能不是属于某一个特定类,有些属性也不是属于某一个特定的类。所以我们就创建了很多的Java工具类和属性的常量类,就像下面这样。

Java代码

1
2
3
public class Constant {
public static final String BASE_URL = "http://www.xxx.top:8080";
}

1
2
3
4
5
6
public class StrUtil {
public static String joinToStr(Collection<String> collection){
//...
return "";
}
}

其实上面的类只是为了承载我们的静态属性和方法,作为了静态方法和属性的容器,这就是我们目前遇到的问题,一大堆无用的容器类,那让我们看看Kotlin中是如何处理这个问题的。

顶层函数

见名知意,原来在Java中,类处于顶层,类包含属性和方法,在Kotlin中,函数站在了类的位置,我们可以直接把函数放在代码文件的顶层,让它不从属于任何类。就像下面这样,我们在一个Str.kt文件中写入如下的Kotlin代码。

Kotlin代码

1
2
3
4
5
6
package util

fun joinToStr(collection: Collection<String>): String{
//....
return "";
}

请注意,我们把它放在了util包中,这在我们厚密啊调用这个类时非常重要。
让我们现来看看在另一个Kotlin类中怎么调用。

Kotlin代码

1
2
3
4
5
import util.joinToStr

fun main(args: Array<String>){
joinToStr(collection = listOf("123", "456"))
}

看到了吗?我们可以通过import 包名.函数名来导入我们将要使用的函数,然后就可以直接使用了,是不是超级方便。那我们再来看看在Java中如何调用上面的方法。

Java代码

1
2
3
4
5
6
7
8
import java.util.ArrayList;
import util.StrKt;

public class Main {
public static void main(String[] args) {
StrKt.joinToStr(new ArrayList<>());
}
}

因为在Java中,类还是必须要存在的,所以编译器将Str.kt文件里的代码放在了一个StrKt的类中,然后把我们定义的Kotlin的函数作为静态方法放在其中,所以在Java中是先通过mport导入这个类,然后通过类名.方法名来调用。

可能有时候你觉得Kotlin为你自动生成的这个类名不好,那你可以通过@file:JvmName注解来自定义类名,就像下面这样。

1
2
3
4
5
6
7
@file:JvmName("StrUtil")
package util

fun joinToStr(collection: Collection<String>): String{
//....
return "";
}

而且要注意,这个注解必须放在文件的开头,包名的前面
在Java中导入类和调用的时候就要使用我们自定义的类名来进行操作了,就像这样。

1
2
3
4
5
6
7
8
import java.util.ArrayList;
import util.StrUtil;

public class Main {
public static void main(String[] args) {
StrUtil.joinToStr(new ArrayList<>());
}
}

顶层属性

了解了顶层函数,下面再看看顶层属性。顶层属性也就是把属性直接放在文件顶层,不依附于类。我们可以在顶层定义的属性包括var变量和val常量,就像下面这样。

Kotlin代码

1
2
3
4
5
6
7
package config

var count = 0

val REQUEST_URL = "http://localhost:8080/"

const val BASE_URL = "http://www.xxx.top/"

这里我定义了三个顶层属性,可能有些地方你还不太能看得懂,不急,我们先看看在Kotlin和Java中怎么用,然后我们再理解。

在Kotlin中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
import config.count

fun main(args: Array<String>){

//使用var变量
count++

//使用val常量
config.REQUEST_URL

//使用const val常量
config.BASE_URL
}

你会发现在Kotlin中只要导入就可以直接使用了,与顶层属性的使用是一样的。

在Java中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import config.ApiConfigKt;

public class Main {
public static void main(String[] args) {

//使用var变量
ApiConfigKt.setCount(12);
System.out.println(ApiConfigKt.getCount());

//使用val常量
System.out.println(ApiConfigKt.getREQUEST_URL());

//使用const val常量
System.out.println(ApiConfigKt.BASE_URL);

}
}

首先导入是肯定的,通过类名类调用这个也和顶层函数里面的规则一致。然后你会发现Kotlin为var变量生成了get和set方法,然后为val常量生成了get方法,最后我们的const val常量则等同于Java的public static final常量,可以直接通过类名.常量名来调用。

写在最后

Kotlin中通过使用顶层函数和顶层属性帮助我们消除了Java中常见的静态工具类,使我们的代码更加整洁,值得一试。

如果博客对您有帮助,不妨请我喝杯咖啡...