美文网首页
Kotlin 中的const关键字

Kotlin 中的const关键字

作者: wind_sky | 来源:发表于2019-07-26 14:37 被阅读0次

    在C、C++等语言中const表示不可修改的常量,在Java中const 是一个保留的标识符,不能用来修饰变量,也不能作为变量名,而它在其他语言中的作用则由final关键字来完成。

    在Kotlin中,可修改的变量用var声明,不可修改的常量用val声明,那么const作用是什么?

    (1)const的作用范围

    const 只能修饰Kotlin的顶级属性(在 .kt 文件中class外声明的属性),或object对象中(object类似Java中的匿名内部类)的属性,并且值被声明为基本类型或String。

    下面是一个声明属性的例子

    Test.kt

    const val topConstValue = "topConstValue"
    val topValue = "topValue"
    
    class Test {
        // const val cc = "cc"  不可在类中声明
        companion object {
            const val compObjConstValue = "compObjConstValue"
            val compObjValue = "compObjValue"
        }
        object obj: A() {
            const val objConstValue = "objConstValue"
            val objValue = "objValue"
        }
    }
    

    上面的代码展示了const使用的场景,作为对比还写了不使用const的变量,下面将展示在其他文件(包括Java和Kotlin)中对这些变量进行访问。

    JavaTest.java

    import com.whx.ktapplication.data.TestKt;
    
    public class JavaTest {
        public void method() {
            println(TestKt.topConstValue);              // 1
            println(TestKt.getTopValue());              // 2
    
            println(Test.compObjConstValue);            // 3
            println(Test.Companion.getCompObjValue());  // 4
    
            println(Test.obj.objConstValue);            // 5
            println(Test.obj.INSTANCE.getObjValue());   // 6
    
        }
    }
    

    可以看出,1、2处Test.kt 文件实际被编译成了TestKt这个类,在访问const修饰的变量时,可以像访问static变量那样直接使用“类名.变量名”的形式,而没有const修饰的变量则需要调用get方法。

    Test类中有companion object,这个的用法在这里,相当于static的作用,和上面一样,有const修饰的变量可以直接访问,没有const修饰的则通过Test类自动生成的Companion类的get方法访问。

    至于产生这种情况的原因,可以看下反编译Kotlin字节码之后的Java形式代码,如下

    反编译的Test.kt字节码

    import kotlin.Metadata;
    import kotlin.jvm.internal.Intrinsics;
    import org.jetbrains.annotations.NotNull;
    
    @Metadata(
    ...  
    )
    public final class TestKt {
       @NotNull
       public static final String topConstValue = "topConstValue";
       @NotNull
       private static final String topValue = "topValue";
    
       @NotNull
       public static final String getTopValue() {
          return topValue;
       }
    
       public static final void main(@NotNull String[] args) {
          Intrinsics.checkParameterIsNotNull(args, "args");
       }
    }
    // Test.java
    package test;
    
    import com.whx.ktapplication.data.A;
    import kotlin.Metadata;
    import kotlin.jvm.internal.DefaultConstructorMarker;
    import org.jetbrains.annotations.NotNull;
    
    @Metadata(
       ...
    )
    public final class Test {
       @NotNull
       public static final String compObjConstValue = "compObjConstValue";
       @NotNull
       private static final String compObjValue = "compObjValue";
       public static final Test.Companion Companion = new Test.Companion((DefaultConstructorMarker)null);
    
       @Metadata(
          ...
       )
       public static final class obj extends A {
          @NotNull
          public static final String objConstValue = "objConstValue";
          @NotNull
          private static final String objValue = "objValue";
          public static final Test.obj INSTANCE;
    
          @NotNull
          public final String getObjValue() {
             return objValue;
          }
    
          private obj() {
             INSTANCE = (Test.obj)this;
             objValue = "objValue";
          }
    
          static {
             new Test.obj();
          }
       }
    
       @Metadata(
          ...
       )
       public static final class Companion {
          @NotNull
          public final String getCompObjValue() {
             return Test.compObjValue;
          }
    
          private Companion() {
          }
    
          // $FF: synthetic method
          public Companion(DefaultConstructorMarker $constructor_marker) {
             this();
          }
       }
    }
    

    相关文章

      网友评论

          本文标题:Kotlin 中的const关键字

          本文链接:https://www.haomeiwen.com/subject/zczrrctx.html