object关键字主要有三种使用场景
- 对象声明(object declaration)
- 伴生对象(companion object)
- 对象表达式(object expression)
对象声明(object declaration)
- 将类的声明和定义该类的单例对象结合在一起(即通过object就实现了单例模式)
- 对象声明中不能包含构造器(包括主构造器和次级构造器)
Kotlin实现及调用
object KotlinTest {
public var a = 0;
}
fun main() {
var b = KotlinTest.a;
}
转成Java及调用
public final class KotlinTest {
@NotNull
public static final KotlinTest INSTANCE;
private KotlinTest() {
}
static {
KotlinTest var0 = new KotlinTest();
INSTANCE = var0;
}
}
//java 调用
public JavaTest() {
int a = KotlinTest.INSTANCE.getA();
}
Kotlin 中的 object 本质上就是 Java 中简单的单例模式,同时它的构造方法是 private 的,因此 object 类不能自定义构造方法!
伴生对象(companion object)
在 Kotlin 中是没有 static 关键字的!想要实现通过 类名.xxx() 的方式调用工具方法,可以使用上述的 object 类,但 object 本身就是一个对象,我们无法在外部调用其构造方法,既然想拥有 object 类(通过类名调用方法)与 class 类(外部可以调用构造方法)的两种特性,这时伴生对象 companion object 就完全可以满足这个需求:
Kotlin实现及调用
class KotlinTest {
companion object {
var a = 0;
fun test() {}
}
fun main() {
val b: Int = KotlinTest.a;
}
}
转成Java及调用
public final class KotlinTest {
private static int a;
@NotNull
public static final KotlinTest.Companion Companion = new KotlinTest.Companion((DefaultConstructorMarker)null);
public static final class Companion {
public final int getA() {
return KotlinTest.a;
}
public final void setA(int var1) {
KotlinTest.a = var1;
}
public final void test() {
}
private Companion() {
}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}
//java 调用
public class JavaTest {
public JavaTest() {
int a = KotlinTest.Companion.getA();
}
}
Kotlin 中的 companion object 其实对应到 Java 中也就只是 一个静态内部类实例而已。当类中成员和伴生对象中成员重名的时候,类名调用的是伴生对象中的,实例调用的是类中的。
对象表达式(object expression)
对象表达式常用来作为匿名内部类的实现
// 通过对象表达式实现点击事件回调
btn.setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
TODO("Not yet implemented")
}
})
@JvmField、 @JvmStatic
在对象声明和伴生对象中,java代码调用总会跟上INSTANCE或者Companion,Kotlin 中 的伴生对象本质上就是静态实例,如果想像kotlin代码那样直接调用,需要使用kotlin自带的注解:@JvmStatic或者@JvmField
对于对象声明
object KotlinTest {
@JvmField
var a = 0;
}
转换的java代码
public final class KotlinTest {
@JvmField
public static int a;
@NotNull
public static final KotlinTest INSTANCE;
private KotlinTest() {
}
static {
KotlinTest var0 = new KotlinTest();
INSTANCE = var0;
}
}
java代码中在KotlinTest类中增加了静态成员属性
对于伴生对象
class KotlinTest {
companion object {
@JvmField
public var a = 0;
@JvmStatic
fun test() {
}
}
}
转换的java代码
public final class KotlinTest {
@JvmField
public static int a;
@NotNull
public static final KotlinTest.Companion Companion = new KotlinTest.Companion((DefaultConstructorMarker)null);
@JvmStatic
public static final void test() {
Companion.test();
}
public static final class Companion {
@JvmStatic
public final void test() {
}
private Companion() {
}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}
增加了对应的 static 属性和方法
顶层函数
fun print() {
}
class KotlinTest {
}
转换成Java
public final class KotlinTest {
}
// KotlinTestKt.java
public final class KotlinTestKt {
public static final void print() {
}
}
在JVM中它会生成一个类,类的名字就是你的文件名加上Kt。这个文件中的所有顶层函数编译为这个类的静态函数。因此当从Java中调用这个函数的时候和调用任何其他静态函数一样。
要修改包含kotlin顶层函数的生成的类的名称,需要为这个文件添加@JvmName注解,将其放到文件开头,位于包名前面
@file:JvmName("PrintUtils")
package com.utils
fun print() {
}
class KotlinTest {
}
转换成Java
public final class KotlinTest {
}
// PrintUtils.java
package com.utils;
import kotlin.Metadata;
import kotlin.jvm.JvmName;
@JvmName(
name = "PrintUtils"
)
public final class PrintUtils {
public static final void print() {
}
}
单例
class KotlinTest {
private constructor() {
}
companion object {
val instance:KotlinTest by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
KotlinTest()
}
}
}
网友评论