Kotlin實現靜態方法與靜態變量的兩種方式

1. 新建.kt文件(不是Class等), 直接在kt文件中寫方法

示例Utils.kt

@file:JvmName("Utils")
package com.demo.android.utils

import android.util.Log

const val TAG = "Utils"
var msg = "This is a static function"

fun staticFun() {
    Log.d(TAG, msg)
}
複製代碼

咱們能夠經過Android Studio中的Tools -> kotlin -> Show Kotlin Bytecode -> Decompile到java代碼查看java

package com.demo.android.utils;

import android.util.Log;
import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

public final class Utils {
   @NotNull
   public static final String TAG = "Utils";
   @NotNull
   private static String msg = "This is a static function";

   @NotNull
   public static final String getMsg() {
      return msg;
   }

   public static final void setMsg(@NotNull String var0) {
      Intrinsics.checkParameterIsNotNull(var0, "<set-?>");
      msg = var0;
   }

   public static final void staticFun() {
      Log.d("Utils", msg);
   }
}

複製代碼

咱們能夠看到Java代碼是生成了一個名爲UtilsKt的Class文件, 而staticFun就是一個靜態方法了, TAG就是一個靜態常量, msg也就是一個靜態變量. 當咱們加上@file:JvmName("Utils")的註解, 而後生成的Java類名也就是Utils了.android

###在Kotlin或者Java代碼中調用markdown

  1. 在kotlin中調用app

    package com.demo.android
    
    import android.os.Bundle
    import androidx.appcompat.app.AppCompatActivity
    import com.demo.android.utils.staticFun
    
    class DemoActivity: AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            staticFun()
        }
    }
    複製代碼

    在kotlin中調用的話, 是沒法使用class.fun的方式的, 只能直接引用方法名, import的也是方法名jvm

    反編譯成javaide

    package com.demo.android;
    
    import android.os.Bundle;
    import android.view.View;
    import androidx.appcompat.app.AppCompatActivity;
    import com.demo.android.utils.Utils;
    import java.util.HashMap;
    import kotlin.Metadata;
    import org.jetbrains.annotations.Nullable;
    
    public final class DemoActivity extends AppCompatActivity {
    
       protected void onCreate(@Nullable Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          Utils.staticFun();
          // 若是不增長@file:JvmName("Utils")的註解
         	// UtilsKt.staticFun()
       }
    }
    複製代碼
  2. 在java中調用就跟上方反編譯成java同樣工具

2. 在objects或者companion objects中加上@JvmStatic的註解

Utils.kt

@file:JvmName("Utils")
package com.demo.android.utils

import android.util.Log

object Utils {
    const val TAG = "Utils"
    var msg = "This is a static function"

    fun staticFun() {
        Log.d(TAG, msg)
    }
}
複製代碼

反編譯成javaspa

package com.vova.android.utils;

import android.util.Log;
import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

public final class Utils {
   @NotNull
   public static final String TAG = "Utils";
   @NotNull
   private static String msg;
   public static final Utils INSTANCE;

   @NotNull
   public final String getMsg() {
      return msg;
   }

   public final void setMsg(@NotNull String var1) {
      Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
      msg = var1;
   }

   public final void staticFun() {
      Log.d("Utils", msg);
   }

   private Utils() {
   }

   static {
      Utils var0 = new Utils();
      INSTANCE = var0;
      msg = "This is a static function";
   }
}
複製代碼

在單例類Utils中, 咱們能夠看到全部的變量都是靜態變量, 而方法在沒有@JvmStatic的註解時, 不是靜態方法,code

變量msgget() set()方法也不是靜態方法orm

增長@JvmStatic註解

@file:JvmName("Utils")
package com.demo.android.utils

import android.util.Log

object Utils {
    const val TAG = "Utils"
    @JvmStatic
    var msg = "This is a static function"

    @JvmStatic
    fun staticFun() {
        Log.d(TAG, msg)
    }
}
複製代碼

反編譯成java

package com.demo.android.utils;

import android.util.Log;
import kotlin.Metadata;
import kotlin.jvm.JvmStatic;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

public final class Utils {
   @NotNull
   public static final String TAG = "Utils";
   @NotNull
   private static String msg;
   public static final Utils INSTANCE;

   /** @deprecated */
   // $FF: synthetic method
   @JvmStatic
   public static void msg$annotations() {
   }

   @NotNull
   public static final String getMsg() {
      return msg;
   }

   public static final void setMsg(@NotNull String var0) {
      Intrinsics.checkParameterIsNotNull(var0, "<set-?>");
      msg = var0;
   }

   @JvmStatic
   public static final void staticFun() {
      Log.d("Utils", msg);
   }

   private Utils() {
   }

   static {
      Utils var0 = new Utils();
      INSTANCE = var0;
      msg = "This is a static function";
   }
}
複製代碼

增長@JvmStatic註解後, 咱們能夠看到staticFun()與變量msgget() set()也都是靜態方法了

**companion objects**同理

在Kotlin或者Java代碼中調用

  1. 在kotlin中調用

    package com.demo.android
    
    import android.os.Bundle
    import androidx.appcompat.app.AppCompatActivity
    import com.demo.android.utils.Utils
    
    class DemoActivity: AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            Utils.staticFun()
          	Utils.msg
        }
    }
    複製代碼

    反編譯成java

    package com.vova.android;
    
    import android.os.Bundle;
    import android.view.View;
    import androidx.appcompat.app.AppCompatActivity;
    import com.vova.android.utils.Utils;
    import java.util.HashMap;
    import kotlin.Metadata;
    import org.jetbrains.annotations.Nullable;
    
    public final class DemoActivity extends AppCompatActivity {
    
       protected void onCreate(@Nullable Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          Utils.staticFun();
          Utils.getMsg();
       }
    
    }
    複製代碼

    在java中調用與反編譯成java相同

總結

在java中咱們寫工具類時, 一般都是使用靜態方法來實現, 而在kotlin中, 一般是使用object類,

而object類就是一個單例, 相對於直接引用靜態方法總會new一個對象.

上面介紹的靜態方法, 第一種其實與咱們平時在java中實現相同, 可是引用方式不一樣, 因此我如今更喜歡在kotlin項目中使用object來寫工具類

相關文章
相關標籤/搜索