kotlin学习笔记:object关键字介绍与java中的静态变量与静态⽅法的实现以及
@J。。。
在java中,静态变量和静态⽅法是我们经常需要⽤到的东西,但是我们在kotlin中,并不能到static关键字。其实⽬前在kotlin中,也的确是static概念的,那么我们该如何在kotlin中实现静态变量和静态⽅法呢?这时就要⽤到kotlin中的object关键字了,下⾯⽂章的内容会将object的⽤法和静态的实现⼀起详细讲解
Tip: 想要⾃⼰验证本⽂内容的⼩伙伴,请看⽂章
推荐
kotlin中的object
从字⾯意思看,object的意思即是对象,实际上也确实如此,但是如此解释也未免过于抽象了!所以我们通过⼏个例⼦来看object。
⾸先,我们要知道object的⼏种使⽤场景:
对象声明
伴⽣对象
对象表达式
⼀、对象声明
object Test{
}
⼀般声明⼀个类,我们⽤class,此处我们使⽤object来声明⼀个类,⽽在此同时也声明了它的⼀个对象。我们看⼀下,将kotlin转换
成java后的代码:
public final class Test {
public static final Test INSTANCE;
static{
Test var0 =new Test();
INSTANCE = var0;
}
}
从转换成的java代码中,我们可以清楚的看到,在Test类中,同时声明了⼀个Test的静态变量对象INSTANCE,不仅如此,还形成了⼀个简单的单例模式,如果觉得这个不像,那么转换⼀下:
public final class Test {
private static final Test INSTANCE =new Test();
public static Test getInstance(){
return INSTANCE;
}
// 必须注意的⼀点
private Test(){
}
}
看到这个,是否觉得有点眼熟了呢?
不过有⼀点要注意,可能你们也发现了,kolin转换成的java代码中,没有将构造参数设为private,⽽我⾃⼰转换的却将构造参数设为
了private,这是为什么呢?下⾯请看对Test类的调⽤
这下写的很明⽩了,直接提⽰private,所以其实第⼆段java代码才是kotlin转换后的完整版,⾄于为什么编译器转换出来的没有写明构造函数为private,就不得⽽知了。
所以,总结object在以上的使⽤中,有两点
object声明⼀个类时,该类⾃动成为⼀个简单的单例模式
object声明的类,⽆法在外部⽤new的⽅式重新实例化
代替static的第⼀种⽅法
看了上⾯的object的对象声明,下⾯就可以来说⼀下,第⼀种代替静态的⽅法啦!没错,就是使⽤object类!
下⾯是kotlin中的代码
object Test {
var code =1
fun getData(){
}
}
编译成java代码
public final class Test {
private static int code;
public static final Test INSTANCE;
public final int getCode(){
return code;
}
public final void setCode(int var1){
code = var1;
}
public final void getData(){
}
static{
Test var0 =new Test();
INSTANCE = var0;
code =1;
}
}
可以看到,在转换成的java代码中,int型的code变量与getCode()⽅法都变成静态的了,下⾯再来看看如何调⽤
在kotlin中调⽤
private fun check(){
val code = de
}
在java中调⽤
private void check(){
Code();
Data();
}
我们可以看到,在java中调⽤时,我们必须通过INSTANCE来进⾏,并且code的获取使⽤了get⽅法,其实这点在上⾯转换代码中就可以看到转换成的code是private的,并不是静态变量,并且⾃动⽣成了getter和setter⽅法。⽽对于getData()⽅法,其实也不是真正的静态⽅法,都是基于单例来实现的
对于这点,有些⼈可能是接受不了的,并且觉得内部的java实现很糟糕,想要渴求真正的静态,那么该如何解决呢?这下就得我们
的@JvmField与@JvmStatic注解出场的时候了
@JvmField与@JvmStatic的出场
我们先看代码,
⾸先是kotlin代码:
object Test {
@JvmField
var code =1
@JvmStatic
fun getData(){
}
}
然后是转换后的java代码:
public final class Test {
@JvmField
学习java的学习方法
public static int code;
public static final Test INSTANCE;
@JvmStatic
public static final void getData(){
}
static{
Test var0 =new Test();
INSTANCE = var0;
code =1;
}
我们发现,code变成真正的静态变量,⽽getData()⽅法也变成了真正的静态⽅法,下⾯是⼀些注意点
@JvmField消除了变量的getter与setter⽅法
@JvmField修饰的变量不能是private属性的
@JvmStatic只能在object类或者伴⽣对象companion object中使⽤,⽽@JvmField没有这些限制
@JvmStatic⼀般⽤于修饰⽅法,使⽅法变成真正的静态⽅法;如果修饰变量不会消除变量的getter与setter⽅法,但会
使getter与setter⽅法和变量都变成静态,看例⼦
kotlin代码
object Test {
@JvmStatic
var code =1
}
转换后的java代码
public final class Test {
private static int code;
public static final Test INSTANCE;
/** @deprecated */
// $FF: synthetic method
@JvmStatic
public static void code$annotations(){
}
public static final int getCode(){
return code;
}
public static final void setCode(int var0){
code = var0;
}
static{
Test var0 =new Test();
INSTANCE = var0;
code =1;
}
}
⼆、伴⽣对象
在kotlin中每个类都可以给⾃⼰构造⼀个伴⽣对象companion object,看代码
class Test {
// MyTest 是伴⽣对象的名字,可以不写,不写默认为 companion
companion object MyTest{
var code =1
fun getData(){
}
}
}
转换后的java代码
public final class Test {
private static int code =1;
public static final Test.MyTest MyTest =new Test.MyTest((DefaultConstructorMarker)null);
@Metadata(
mv ={1,1,10},
bv ={1,0,2},
k =1,
d1 ={"\u0000\u001a\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\b\n\u0002\b\u0005\n\u0002\u0010\u0002\n\u0000 \b\u0086\u0003\u0018\u00002\u00020\u0001B\u0007\b\u0002¢\u0006\u0002\u0010\u0002J\u0006\u0010\t\u001a\u00020\nR\u001a\u0010\u0003\u001 a\u00020\u0004X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\u0005\u0010\u0006\"\u0004\b\u0007\u0010\b¨\u0006\u000b"},
d2 ={"Lcom/homeprint/module/mine/Test$MyTest;","","()V","code","","getCode","()I","setCode","(I)V","getData","","production sources for modul e module_mine"}
)
public static final class MyTest {
public final int getCode(){
de;
}
public final void setCode(int var1){
}
public final void getData(){
}
private MyTest(){
}
// $FF: synthetic method
public MyTest(DefaultConstructorMarker $constructor_marker){
this();
}
}
}
可以看出,转换后的java代码中,⽣成了⼀个MyTest的静态类,通过这个MyTest来管理我们的code和getData(),但其实这也没有真正的实现我们想要的静态
kotlin中的调⽤
private fun check(){
// ⽅式 1
val code = de
// ⽅式 2
val code1 =de
Data()
}
java中的调⽤
private void check(){
Code();
Data();
}
可以看出,在kotlin中调⽤时,可以选择写或者不写MyTest静态类,两种⽅式,但是在java中必须得写MyTest。那么如何实现我们想要的真正静态呢?和上述 对象声明 中使⽤⼀样的⽅法(@JvmField和@JvmStatic)。
kotlin的代码:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。