Kotlin编译流程

Kotlin编译流程

Kotlin编译流程

Kotlin代码经过编译器边后,生成Java字节码,这种字节码是专门为JVM设计的,JVM拿到字节码后,会根据特定的语法解析其中的内容,并让字节码运行起来。
Java和Kotlin本质是在用同一种语言进行沟通的。

在这里插入图片描述

使用AS工具

可以使用AndroidStudio的工具:点击菜单栏 -> Tool -> Kotlin -> Show Kotlin Bytecode,查看生成的Java字节码;

还可以点击顶部的"Decompile"按钮查看翻译后的Java代码。

Kotlin与Java代码对比

println

Kotlin代码

println("hello world")

翻译为Java代码

String var0 = "hello world";
System.out.println(var0);

Kotlin类型

Kotlin代码

val a: Long = 1L
val b: Long? = 2L

var c: Long = 3L
var d: Long? = 4L

val e: Long? = null
var f: Long? = null

var g: Long? = 5L
g = null

var h: Long? = null
h = 6L

翻译为Java代码

long a = 1L;
long b = 2L;

long c = 3L;
long d = 4L;

Long e = (Long)null;
Long f = (Long)null;

Long g = 5L;
g = (Long)null;

Long h = (Long)null;
h = 6L;

说明:变量a、b、c、d被Kotlin转换为Java的原始类型long,而e、f、g、h则被转换为包装类型Long。

转换规则:如果变量可能为空,则被转换为Java的包装类型;如果变量不可能为空,则被转换为Java的原始类型。

类型推导

Kotlin代码

val a = 100L
val b = "hello"

翻译为Java代码

long a = 100L;
String b = "hello";

说明:在写Kotlin代码的时候省略的类型,最终会被编译器补充回来。

字符串模板

Kotlin代码

val a = """
        姓名:$name
        年龄:$age
    """

翻译为Java代码

String a = "\n        姓名:" + name + "\n        年龄:" + age + "\n    ";

说明:编译器最终会将它们转换程Java字符串拼接的形式。

when表达式

Kotlin代码

fun foo(a: Any) {
    when (a) {
        is Int -> println("Int")
        is Boolean -> println("Boolean")
        is String -> println("String")
        else -> println("unknown")
    }
}

fun foo2(a: String) {
    when (a) {
        "AAA" -> println("A")
        "BBB" -> println("B")
        "CCC" -> println("C")
        else -> println("else")
    }
}

翻译为Java代码

public static final void foo(@NotNull Object a) {
    Intrinsics.checkNotNullParameter(a, "a");
    String var2;
    if (a instanceof Integer) {
        var2 = "Int";
        System.out.println(var2);
    } else if (a instanceof Boolean) {
        var2 = "Boolean";
        System.out.println(var2);
    } else if (a instanceof String) {
        var2 = "String";
        System.out.println(var2);
    } else {
        var2 = "unknown";
        System.out.println(var2);
    }
}

public static final void foo2(@NotNull String a) {
    String var2;
    switch(a.hashCode()) {
        case 64545:
            if (a.equals("AAA")) {
                var2 = "A";
                System.out.println(var2);
                return;
            }
            break;
        case 65538:
            if (a.equals("BBB")) {
                var2 = "B";
                System.out.println(var2);
                return;
            }
            break;
        case 66531:
            if (a.equals("CCC")) {
                var2 = "C";
                System.out.println(var2);
                return;
            }
    }
    var2 = "else";
    System.out.println(var2);
}

说明:编译器最终会将它们转换为类似switch-case和if-else形式。

Java的switch-case支持’char, byte, short, int, Character, Byte, Short, Integer, String, or an enum’,其中String是Java 1.7及以后才支持的,而Kotlin是完全兼容Java 1.6的。

Kotlin代码

open class Base {
    var country = "中国"
}

class Person(val name: String, val age: Int) : Base() {

}

翻译为Java代码

public class Base {
    @NotNull
    private String country = "中国";

    @NotNull
    public final String getCountry() {
        return this.country;
    }

    public final void setCountry(@NotNull String var1) {
        this.country = var1;
    }
}

public final class Person extends Base {
    @NotNull
    private final String name;
    private final int age;

    @NotNull
    public final String getName() {
        return this.name;
    }

    public final int getAge() {
        return this.age;
    }

    public Person(@NotNull String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
}

说明:

  • var变量会被编译器转换为get/set方法,val变量会被编译器转换为get方法。
  • 省略的public最终会被编译器补充。

抽象类

abstract class AbsBase {
    abstract val isAult: Boolean

    abstract fun say()

    fun run() {}
}

class Chinese(val name: String, val age: Int) : AbsBase() {
    override val isAult: Boolean
	    get() = age >= 18

    override fun say() {
        println("hello world")
    }
}

翻译为Java代码

public abstract class AbsBase {
    public abstract boolean isAult();

    public abstract void say();

    public final void run() {
    }
}

public final class Chinese extends AbsBase {
    @NotNull
    private final String name;
    private final int age;

    public Chinese(@NotNull String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public boolean isAult() {
        return this.age >= 18;
    }

    public void say() {
        String var1 = "hello world";
        System.out.println(var1);
    }

    @NotNull
    public final String getName() {
        return this.name;
    }

    public final int getAge() {
        return this.age;
    }   
}

说明:

  • isAult属性被编译器转换为抽象方法。

接口

Kotlin代码

interface IBase {
    val isForeign: Boolean

    fun say()

    fun eat() {
        println("吃饭")
    }
}

class Chinese(val name: String, var age: Int) : IBase {
    val isAdult
    	get() = age >= 18

    override val isForeign: Boolean = false

    override fun say() {
        println("说中文")
    }

    override fun eat() {
        super.eat()
        println("吃中餐")
    }
}

翻译为Java代码

public interface IBase {
    boolean isForeign();

    void say();

    void eat();

    public static final class DefaultImpls {
        public static void eat(@NotNull IBase $this) {
            String var1 = "吃饭";
            System.out.println(var1);
        }
    }
}

public final class Chinese implements IBase {
   private final boolean isForeign;
   @NotNull
   private final String name;
   private int age;

   public final boolean isAdult() {
      return this.age >= 18;
   }

   public boolean isForeign() {
      return this.isForeign;
   }

   public void say() {
      String var1 = "说中文";
      System.out.println(var1);
   }

   public void eat() {
      IBase.DefaultImpls.eat(this);
      String var1 = "吃中餐";
      System.out.println(var1);
   }

   @NotNull
   public final String getName() {
      return this.name;
   }

   public final int getAge() {
      return this.age;
   }

   public final void setAge(int var1) {
      this.age = var1;
   }

   public Chinese(@NotNull String name, int age) {
      super();
      this.name = name;
      this.age = age;
   }
}

说明:

  • Kotlin中的接口方法实现被编译器转换为静态内部类,虽然Java 1.8支持了接口方法实现,但是Kotlin是基于Java 1.6设计的,所以通过静态内部类实现。
  • 接口中的isForeign属性会被编译器转换为抽象方法。
  • 实现类中的isAdult属性会被编译器转化为get方法。

数据类

不设置默认值

Kotlin代码

data class Student(val name: String, val age: Int)

翻译为Java代码

public final class Student {
    @NotNull
    private final String name;
    private final int age;

    @NotNull
    public final String getName() {
        return this.name;
    }

    public final int getAge() {
        return this.age;
    }

    public Student(@NotNull String name, int age) {
        Intrinsics.checkNotNullParameter(name, "name");
        super();
        this.name = name;
        this.age = age;
    }

    @NotNull
    public final String component1() {
        return this.name;
    }

    public final int component2() {
        return this.age;
    }

    @NotNull
    public final Student copy(@NotNull String name, int age) {
        Intrinsics.checkNotNullParameter(name, "name");
        return new Student(name, age);
    }

    // $FF: synthetic method
    public static Student copy$default(Student var0, String var1, int var2, int var3, Object var4) {
        if ((var3 & 1) != 0) {
            var1 = var0.name;
        }

        if ((var3 & 2) != 0) {
            var2 = var0.age;
        }

        return var0.copy(var1, var2);
    }

    @NotNull
    public String toString() {
        return "Student(name=" + this.name + ", age=" + this.age + ")";
    }

    public int hashCode() {
        String var10000 = this.name;
        return (var10000 != null ? var10000.hashCode() : 0) * 31 + Integer.hashCode(this.age);
    }

    public boolean equals(@Nullable Object var1) {
        if (this != var1) {
            if (var1 instanceof Student) {
                Student var2 = (Student)var1;
                if (Intrinsics.areEqual(this.name, var2.name) && this.age == var2.age) {
                    return true;
                }
            }

            return false;
        } else {
            return true;
        }
    }
}
全设置默认值

Kotlin代码

data class Student(val name: String = "小明", val age: Int = 18)

翻译为Java代码


public final class Student {
    @NotNull
    private final String name;
    private final int age;

    @NotNull
    public final String getName() {
        return this.name;
    }

    public final int getAge() {
        return this.age;
    }

    public Student(@NotNull String name, int age) {
        Intrinsics.checkNotNullParameter(name, "name");
        super();
        this.name = name;
        this.age = age;
    }

    // $FF: synthetic method
    public Student(String var1, int var2, int var3, DefaultConstructorMarker var4) {
        if ((var3 & 1) != 0) {
            var1 = "小明";
        }

        if ((var3 & 2) != 0) {
            var2 = 18;
        }

        this(var1, var2);
    }

    public Student() {
        this((String)null, 0, 3, (DefaultConstructorMarker)null);
    }

    @NotNull
    public final String component1() {
        return this.name;
    }

    public final int component2() {
        return this.age;
    }

    @NotNull
    public final Student copy(@NotNull String name, int age) {
        Intrinsics.checkNotNullParameter(name, "name");
        return new Student(name, age);
    }

    // $FF: synthetic method
    public static Student copy$default(Student var0, String var1, int var2, int var3, Object var4) {
        if ((var3 & 1) != 0) {
            var1 = var0.name;
        }

        if ((var3 & 2) != 0) {
            var2 = var0.age;
        }

        return var0.copy(var1, var2);
    }

    @NotNull
    public String toString() {
        return "Student(name=" + this.name + ", age=" + this.age + ")";
    }

    public int hashCode() {
        String var10000 = this.name;
        return (var10000 != null ? var10000.hashCode() : 0) * 31 + Integer.hashCode(this.age);
    }

    public boolean equals(@Nullable Object var1) {
        if (this != var1) {
            if (var1 instanceof Student) {
                Student var2 = (Student)var1;
                if (Intrinsics.areEqual(this.name, var2.name) && this.age == var2.age) {
                    return true;
                }
            }

            return false;
        } else {
            return true;
        }
    }
}
总结
  • Kotlin中的数据类会自动生成copy()toString()hashCode()equals()方法。
  • 数据类的属性如果不设置默认值,则不会生成无参构造函数,如Person类,只会生成2个参数的构造函数。
  • 数据类的属性如果全设置默认值,会生成无参构造函数,如Person类,会生成无参构造函数和2个参数的构造函数。

@JvmOverloads

Kotlin代码

class Person {
    @JvmOverloads
    fun printInfo(name: String = "小明", age: Int = 18) {

    }
}

翻译为Java代码

public final class Person {
    @JvmOverloads
    public final void printInfo(@NotNull String name, int age) {
        Intrinsics.checkNotNullParameter(name, "name");
    }  

    @JvmOverloads
    public final void printInfo(@NotNull String name) {
        printInfo$default(this, name, 0, 2, (Object)null);
    }

    @JvmOverloads
    public final void printInfo() {
        printInfo$default(this, (String)null, 0, 3, (Object)null);
    }
}

说明:使用@JvmOverloads后,会自动生成3个构造函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值