object 对象声明
java 中 要声明一个静态类 ,必需声明成静态内部类,也就是必须依赖非静态的类,
而且 java 中的静态变量,静态方法,和非静态的 方法放在了一起。这种方式是混乱的,所以Kotlin 引入了 object 对象声明 。就像声明一个变量一样,声明一个静态对象(不需要调用构造器获得)。
对象声明的初始化过程是线程安全的并且在首次访问时进行。
需引用该对象,我们直接使用其名称即可:
object SingleName{
var name:String = "xiao 黑"
}
fun main(){
print(SingleName.name)
}
反编译的代码:
可以看出: object 声明的 对象 在JVM 平台上被编译成了静态对象,名称为INSTANCE
,而且 object 声明的对象 其成员也是 静态的。
public final class SingleName {
@NotNull
private static String name;
public static final SingleName INSTANCE;
@NotNull
public final String getName() {
return name;
}
public final void setName(@NotNull String var1) {
Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
name = var1;
}
private SingleName() {
}
static {
SingleName var0 = new SingleName();
INSTANCE = var0;
name = "xiao 黑";
}
}
在Java 平台上,访问 SingleName 的属性,需要以 SingleName.INSTANCE.getName()的形式。
如果我们想 让name 属性 在JVM 平台上被编译成public 。可以使用 @JvmField 关键字
对属性public 化,或者 @JvmStatic 对方法 public 化
object SingleName{
@JvmField var name:String = "xiao 黑"
}
反编译
public final class SingleName {
@JvmField
@NotNull
public static String name;
public static final SingleName INSTANCE;
private SingleName() {
}
static {
SingleName var0 = new SingleName();
INSTANCE = var0;
name = "xiao 黑";
}
}
companion 关键字
如果在类内部声明 使用一个 object 声明 。不带companion 关键字的话 和 外部声明没有区别。
加了companion 关键字。
class SimpleClass {
companion object StaticOBj{
var name:String = " 带 companion 关键字的 "
}
}
反编译:
public final class SimpleClass {
@NotNull
private static String name = " 带 companion 关键字的 ";
public static final SimpleClass.StaticOBj StaticOBj = new SimpleClass.StaticOBj((DefaultConstructorMarker)null);
public static final class StaticOBj {
@NotNull
public final String getName() {
return SimpleClass.name;
}
public final void setName(@NotNull String var1) {
Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
SimpleClass.name = var1;
}
private StaticOBj() {
}
// $FF: synthetic method
public StaticOBj(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}
可以发现 外部类是持有 StaticOBj 的引用的 。也就是该object 相当 外部类的一个静态成员变量。
使用方式:
fun main(){
// 使用 外部类 命调用 对象声明的属性,和方法
print(SimpleClass.name)
}
object 表达式
有时候,我们需要创建一个对某个类做了轻微改动的类的对象,而不用为之显式声明新的子类。 Kotlin 用对象表达式 来处理这种情况。常见的情况就是匿名内部类。但是 对象表达式比它更强大,可以继承和实现接口( 匿名内部类智能继承一个类或者实现一个接口)
对象表达式的形式: object :XXX{
}
val obj = object :Runnable{
override fun run() {
TODO("Not yet implemented")
}
}