工作中,我们总会积累一些通用的工具类、方法、或者属性。通常我们会将相关联的静态方法抽到一个静态类中,慢慢形成我们自己的工具类;有时候某个业务类中也可能会出现静态方法,或者静态属性。
在 Java 中处理静态类、方法、属性都是很轻松的。而 Kotlin 作为 Google 大力推广的 Android 开发语言,虽然和 Java 做到了最大程度的兼容,同一个项目中可以混合使用,互相调用,没有任何限制;但因语法差异,在静态类、函数、属性这一块的处理也还是有一些差异的。
下面将简单介绍一下最近碰到的几种情况。
一、静态类
我们通常将一类静态方法封装到一个独立的工具类中,这个类就是“静态类”(这么叫不准确,但没想到更好的叫法)。
举个栗子
为了方便管理 log,在 release 版本关闭 log,debug 版本打开 log,我们可以对 Log 类进行封装,添加版本判断。
java实现
Java 代码的实现方式就是这样的:
public class LogUtils {
public static void e(String tag, String msg) {
if (BuildConfig.DEBUG) {
Log.e(tag, msg);
}
}
}
这段代码很好懂,接着我们看下 Kotlin 的实现方法。
Kotlin实现
Kotlin 中,要实现一个静态类,需要使用关键字object
去替代 Java 的class
,就是这样:
object LogUtils {
fun e(tag: String, msg: String) {
if (BuildConfig.DEBUG) {
Log.e(tag, msg)
}
}
}
此时 LogUtils 是静态的,其中的所有fun
也都是静态的,可以直接通过LogUtils.fun()
调用。
二、静态代码块
上面已经介绍了静态类,可以看到在静态类这方面 Kotlin 和 Java 的差异其实并不大。但是实际开发中,有时候非静态的业务类中也会出现静态方法,此时使用object
关键字就不行了。
举个栗子
比如我们在使用 Fragment 时,不建议直接调用 Fragment 的构造方法构造 Fragment 对象,而是在 Fragment 内部提供一个静态的实例化方法,就像这样:
Java实现
public class SimpleFragment extends Fragment {
public static SimpleFragment newInstance() {
return new SimpleFragment();
}
}
那么这种情况 Kotlin 要怎么实现呢?
Kotlin实现
Kotlin 提供了另一个关键字:companion
,使用companion
和object
就可以在非静态类中构建静态的代码块,就只这个样子:
class SimpleFragment : Fragment() {
companion object {
fun newInstance(): SimpleFragment {
return SimpleFragment()
}
}
}
此时companion object
中的所有方法都是静态的,调用的时候和java一样:
SimpleFragment.newInstance()
三、静态属性
相信很多人看到上面的静态代码块,就已经知道如何定义静态属性了,但做事还是要有始有终,因此这里还是再说一下。
Java实现
public class SimpleFragment extends Fragment {
public static String KEY = "SimpleFragment";
}
Kotlin实现
class SimpleFragment : Fragment() {
companion object {
var KEY = "SimpleFragment"
fun newInstance(): SimpleFragment {
return SimpleFragment()
}
}
}
很简单,用companion object
包起来就可以了。
补充
Java 和 Kotlin 虽然可以没有限制的相互调用。但在静态代码调用方面有一些差异。而且主要表现在Java 调用 Kotlin
的代码,下面以前面的几个栗子为例,简单说下调用方式。
1、Java 调用 Kotlin 静态类的函数:
LogUtils.INSTANCE.e(tag, msg);
2、Java 调用 companion 中的函数:
SimpleFragment.Companion.newInstance();
3、Java 调用 companion 中的属性:
class SimpleFragment : Fragment() {
companion object {
var KEY = "SimpleFragment"
val KEY2 = "key2"
const val KEY3 = "key3"
}
}
Java中调用就是这样的:
// kEY,var修饰,有get/set
SimpleFragment.Companion.getKEY();
SimpleFragment.Companion.setKEY(key);
// kEY2,val修饰,类似于final,只有get
SimpleFragment.Companion.getKEY2();
// kEY3,只能取值,不能赋值
String key3 = SimpleFragment.KEY3;
此笔记已同步推送到微信公众号:灰灰的Rom笔记