Kotlin與Java混合開發(fā)(3)??Java調(diào)用Kotlin

  • 訪問 Kotlin 屬性

  • 訪問包級(jí)別成員

    • 使用 文件名 訪問
    • 使用 @file:JvmName("自定義名") 訪問
  • 實(shí)例字段铭拧、靜態(tài)字段和靜態(tài)函數(shù)

    • 實(shí)例字段
    • 靜態(tài)字段
    • 靜態(tài)函數(shù)
  • 可見性

  • 生成重載函數(shù)

  • 異常檢查

??Java 調(diào)用 Kotlin 要比 Kotlin 調(diào)用 Java 要麻煩一些,但還是比較容易實(shí)現(xiàn)的锚扎。

一担忧、訪問 Kotlin 屬性

??Kotlin 的一個(gè)屬性對(duì)應(yīng) Java 中的一個(gè)私有字段、一個(gè) setter 函數(shù) 和 一個(gè) getter 函數(shù)养匈,如果是只讀屬性則沒有 setter 函數(shù)哼勇。那么 Java 訪問 Kotlin 的屬性是通過這些 getter 函數(shù) 和 setter 函數(shù)。

// User.kt
data class User(val name: String, var password: String)
// MainJava.java
public class MainJava {

    public static void main(String[] args) {
        User user = new User("小三", "123456");
        System.out.println(user.getName());
        System.out.println(user.getPassword());
        user.setPassword("abcdef");
        System.out.println(user.getPassword());
    }
}
// 運(yùn)行結(jié)果
小三
123456
abcdef
Process finished with exit code 0

??var 聲明的屬性會(huì)生成 gettersetter 兩個(gè)函數(shù)呕乎,但 val 聲明的屬性是只讀的积担,所以只會(huì)生成 getter 一個(gè)函數(shù)。

二猬仁、訪問包級(jí)別成員

??在同一個(gè) Kotlin 文件中帝璧,那些 頂層屬性和函數(shù) (包括頂層擴(kuò)展屬性和函數(shù)) 都不隸屬于某個(gè)類,但它們 隸屬于該 Kotlin 文件中定義的包湿刽。在 Java 中訪問它們時(shí)的烁,把它們當(dāng)成靜態(tài)成員。

  • 使用 文件名 訪問

// 1?? 代碼文件:kot/kotlin_module/src/main/java/cn/ak/kotmodule/kot/topper.kotlin.kt
// 1?? 文件名為:topper.kotlin.kt

package cn.ak.kotmodule.kot

// 頂層函數(shù)
fun rectangleArea(width: Double, height: Double): Double = width * height

// 頂層屬性
val area = 100.0

// 頂層擴(kuò)展函數(shù)
fun User.printInfo() = println("{name=$name, password=$password}")

??上述是一個(gè)名為 topper.kotlin.kt 的 kotlin 源代碼文件诈闺,見第1??行注釋說明渴庆。文件 topper.kotlin.kt 中聲明了一個(gè) 頂層函數(shù)、一個(gè) 頂層屬性 和 一個(gè) User擴(kuò)展函數(shù)雅镊。topper.kotlin.kt 文件編譯后會(huì)生成一個(gè) Topper_kotlinKt.class 文件襟雷,因?yàn)?點(diǎn)(.) 字符不能構(gòu)成 Java 類名,編譯器會(huì)將其 替換下劃線(_)仁烹,所以在 Java 中訪問 topper.kotlin.kt 對(duì)應(yīng)的類名是 Topper_kotlinKt耸弄,見下面調(diào)用案例的第2??~4??行代碼。

// MainJava.java
public class MainJava {

    public static void main(String[] args) {
        // 訪問頂層函數(shù)
        Double area = Topper_kotlinKt.rectangleArea(100, 50); // 2??
        System.out.println(area);
        // 訪問頂層屬性
        System.out.println(Topper_kotlinKt.getArea()); // 3??
        // 訪問擴(kuò)展函數(shù)
        User user = new User("小三", "Lawrence");
        Topper_kotlinKt.printInfo(user); // 4??
    }
}

  • 使用 @file:JvmName("自定義名") 訪問

??如果你覺得上面使用 文件名 來調(diào)用函數(shù)和屬性不夠友好卓缰,但還不想修改 Kotlin 源文件名计呈,那么可以在 Kotlin 源文件中使用 @JvmName 注解,指定生成的文件名征唬,如下面代碼第1??行震叮。

@file:JvmName("ExKotlin")  //1??

package cn.ak.kotmodule.kot

// 頂層函數(shù)
fun rectangleArea(width: Double, height: Double): Double = width * height

// 頂層屬性
val area = 100.0

// 頂層擴(kuò)展函數(shù)
fun User.printInfo() = println("{name=$name, password=$password}")

??注意:@JvmName 注解必須放在 文件的第一行,否則會(huì)報(bào)編譯錯(cuò)誤鳍鸵。

// MainJava.java
public class MainJava {

    public static void main(String[] args) {
        // 訪問頂層函數(shù)
        Double area = ExKotlin.rectangleArea(100, 50);
        System.out.println(area);
        // 訪問頂層屬性
        System.out.println(ExKotlin.getArea());
        // 訪問擴(kuò)展函數(shù)
        User user = new User("小三", "Lawrence");
        ExKotlin.printInfo(user);
    }
}

三苇瓣、實(shí)例字段、靜態(tài)字段和靜態(tài)函數(shù)

??Java 語言中所有的變量和函數(shù)都被封裝到一個(gè)類中偿乖,類中包括實(shí)例函數(shù)(實(shí)例方法)击罪、實(shí)例屬性(成員變量)哲嘲、靜態(tài)屬性(靜態(tài)成員變量) 和 靜態(tài)函數(shù)(靜態(tài)方法),即:Java 中所有東西都放在類中 class 類名 {...}媳禁。

  • 實(shí)例字段

??如果需要以 Java 實(shí)例成員變量形式(即:實(shí)例名.成員變量)訪問 Kotlin 中的屬性眠副,則需要在該屬性前加 @JvmField 注釋,表明該屬性被當(dāng)作 Java 中的成員變量使用竣稽,訪問可見性相同囱怕。另外,延遲初始化(lateinit) 屬性在 Java 中被當(dāng)作成員變量使用毫别,訪問可見性相同娃弓。

// kotlin
class Person {
    // 姓名
    @JvmField  // 1??
    val name = "小三"
    // 年齡
    var age = 20
    // 生日
    lateinit var birthDate: Date // 2??
}
// java
public class MainJava {

    public static void main(String[] args) {
        Person person = new Person();
        System.out.println(person.name);        // 3??
        System.out.println(person.getAge());    // 看不到屬性person.age
        System.out.println(person.birthDate);   // 4??
    }
}

??kotlin 源碼中第1??行使用 @JvmField 注釋聲明 name 屬性,所以代碼第3??行可以直接訪問岛宦。kotlin 源碼第2??行 birthDate 聲明為延時(shí)屬性台丛,而延時(shí)屬性在 Java 源碼中也可以直接訪問。

  • 靜態(tài)字段

??如果需要以 Java 靜態(tài)成員變量形式(即:類名.靜態(tài)成員變量) 訪問 Kotlin 中的屬性砾肺,可以有兩種實(shí)現(xiàn)方法:

??(1) 屬性聲明為頂層屬性挽霉,Java 中將所有的頂層成員(屬性和函數(shù))都認(rèn)為是靜態(tài)的。

// kotlin
@file:JvmName("ExKotlin") 

// 頂層屬性
@JvmField
val area = 100.0

const val MAX_COUNT = 100

??(2) 在 Kotlin 的聲明對(duì)象和伴生對(duì)象中定義屬性变汪,這些屬性需要使用 @JvmField 注解侠坎、lateinitconst 來修飾。什么是伴生對(duì)象裙盾?click me 实胸!

// kotlin
object Singleton {
    @JvmField
    val x = 10

    const val y = 100

    lateinit var birthDate: Date
}

class Size {
    var w = defaultHeight
    var h = 0

    companion object {
        @JvmField
        var defaultHeight = 100

        const val defaultWith = 100

        lateinit var defaultSize: Size
    }
}

調(diào)用上述示例代碼:

// java
public class MainJava {

    public static void main(String[] args) {
        System.out.println("--------------------");
        System.out.println(ExKotlin.area);
        System.out.println(ExKotlin.MAX_COUNT);

        System.out.println("--------------------");
        System.out.println(Singleton.birthDate);
        System.out.println(Singleton.x);
        System.out.println(Singleton.y);

        System.out.println("--------------------");
        System.out.println(Size.defaultWith);
        System.out.println(Size.defaultHeight);
        System.out.println(Size.defaultSize);
    }
}
// 運(yùn)行結(jié)果:
--------------------
100.0
100
--------------------
null
10
100
--------------------
100
100
null

Process finished with exit code 0
  • 靜態(tài)函數(shù)

??如果需要以 Java 靜態(tài)方法形式(即:類名.方法名) 訪問 Kotlin 中的函數(shù),可以有兩種實(shí)現(xiàn)方法:

??(1) 函數(shù)聲明為頂層函數(shù)闷煤,Java 中將所有 kotlin中的頂層函數(shù)(屬性和函數(shù))都認(rèn)為是靜態(tài)的童芹。

// kotlin
@file:JvmName("ExKotlin") 

// 頂層函數(shù)
fun rectangleArea(width: Double, height: Double): Double = width * height

??(2) 在 Kotlin 的聲明對(duì)象(object)伴生對(duì)象(companion object) 中定義函數(shù)涮瞻,這些函數(shù)需要使用 @JvmStatic 來修飾鲤拿。什么是伴生對(duì)象?click me

// kotlin
object Singleton {

    @JvmField
    var x = 10

    @JvmStatic
    fun printlnX() = println("x=$x")
}

class Area {

    companion object {

        @JvmField
        var defaultWith = 100

        @JvmStatic
        fun areaSize(height: Double) = defaultWith * height
    }
}

調(diào)用上述示例代碼:

// java
public class MainJava {

    public static void main(String[] args) {
        System.out.println("---------- 頂層函數(shù) ----------");
        System.out.println(ExKotlin.rectangleArea(100, 20));

        System.out.println("--------------------");
        Singleton.printlnX();

        System.out.println("--------------------");
        System.out.println(Area.areaSize(20));
    }
}
---------- 頂層函數(shù) ----------
2000.0
--------------------
x=10
--------------------
2000.0

Process finished with exit code 0

四署咽、可見性

??Java 和 Kotlin 都有4種可見性近顷,但是除了 public 可以完全兼容外,其他的可見性都是有所區(qū)別的宁否。

  • Java 可見性窒升,默認(rèn)為包私有


    默認(rèn)為包私有
  • Kotlin 可見性

可見性 修飾符 類成員聲明 頂層聲明 說明
公有 public 所有地方可見 所有地方可見 public是默認(rèn)修飾符
內(nèi)部 internal 模塊中可見 模塊中可見 不同于java中的包
保護(hù) protected 子類中可見 頂層聲明中不能使用
私有 private 類中可見 文件中可見

??注意:kotlin 中沒有 Java 的包私有可見性,而具有模塊可見性 (internal)慕匠。

  • 將 Java 可見性 和 Kotlin 可見性對(duì)比饱须,可知 Kotlin 中沒有默認(rèn)包私有可見性,而 Java 中沒有內(nèi)部可見性台谊。
    (1) Kotlin 私有可見性
    ??由于 Kotlin 私有可見性可以聲明類中成員蓉媳,也可以聲明頂層成員譬挚。那么映射到 Java 分為兩種情況:
    ??a、Kotlin 類中私有成員映射到 Java 類中私有實(shí)例成員酪呻。
    ??b减宣、Kotlin 中私有頂層成員映射到 Java 中私有靜態(tài)成員。
    (2) Kotlin 內(nèi)部可見性
    ??由于 Java 中沒有內(nèi)部可見性玩荠,那么 Kotlin 內(nèi)部可見性映射為 Java 公有可見性漆腌。
    (3) Kotlin 保護(hù)可見性
    ??Kotlin 保護(hù)可見性映射為 Java 保護(hù)可見性。
    (4) 公有可見性
    ??Kotlin 公有可見性映射為 Java 公有可見性阶冈。

  • 示例代碼

// KotlinSeeable.kt

internal class Emplyee {
    internal var no: Int = 10   // 內(nèi)部可見性Java端可見

    protected var job: String? = null   // 保護(hù)可見性Java端子類繼承可見

    private var salary: Double = 0.0    // 私有可見性Java端不可見
        set(value) {
            if (value >= 0.0) field = value
        }

    lateinit var dept: Department   // 公有可見性Java端可見
}

open class Department {
    protected var no: Int = 0   // 保護(hù)可見性Java端子類繼承可見

    var name: String = ""   // 公有可見性Java端可見
}

internal const val MAX_IN_COUNT = 300   // 內(nèi)部可見性Java端可見

private const val MIN_IN_COUNT = 0  // 私有可見性Java端不可見

??注意:Kotlin 中 屬性闷尿、函數(shù) 默認(rèn)可見性為public。當(dāng) 函數(shù)眼溶、 沒有被 open 修飾(即:默認(rèn)情況)是可不被繼承狀態(tài)悠砚。

  • 通過 IDE 解釋后的 Java 代碼如下:
public final class Emplyee {
   private int no = 10;
   @Nullable
   private String job;
   private double salary;
   @NotNull
   public Department dept;

   public final int getNo$kotlin_module() {
      return this.no;
   }

   public final void setNo$kotlin_module(int var1) {
      this.no = var1;
   }

   @Nullable
   protected final String getJob() {
      return this.job;
   }

   protected final void setJob(@Nullable String var1) {
      this.job = var1;
   }

   private final void setSalary(double value) {
      if (value >= 0.0D) {
         this.salary = value;
      }

   }

   @NotNull
   public final Department getDept() {
      Department var10000 = this.dept;
      if (var10000 == null) {
         Intrinsics.throwUninitializedPropertyAccessException("dept");
      }

      return var10000;
   }

   public final void setDept(@NotNull Department var1) {
      Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
      this.dept = var1;
   }
}

public class Department {
   private int no;
   @NotNull
   private String name = "";

   protected final int getNo() {
      return this.no;
   }

   protected final void setNo(int var1) {
      this.no = var1;
   }

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

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

public final class KotlinSeeableKt {
   public static final int MAX_IN_COUNT = 300;
   private static final int MIN_IN_COUNT = 0;
}

??注意:當(dāng) Kotlin 類函數(shù)被 Java 解釋時(shí),Kotlin 屬性被映射為 Java 的成員變量堂飞,其修飾符均為 private灌旧,但其 gettersetter 方法的可見性會(huì)與 Kotlin 中屬性可見性對(duì)應(yīng)。lateint 修飾是個(gè)例绰筛,lateinit 修飾可見性保持一致枢泰。

  • Java 調(diào)用 Kotlin 示例
public class MainJava {

    public static void main(String[] args) {
        Emplyee emp = new Emplyee();
        // 訪問kotlin中內(nèi)部可見性的Emplyee成員屬性no
        int no = emp.getNo$kotlin_module();

        Department dept = new Department();
        // 訪問kotlin中公有可見性的Department成員屬性name
        dept.setName("市場(chǎng)部");

        // 訪問Kotlin中公有可見性的Employee成員屬性dept
        emp.setDept(dept);
        System.out.println(emp.getDept());

        // 訪問kotlin中內(nèi)部可見性的頂層屬性MAX_IN_COUNT
        System.out.println(KotlinSeeableKt.MAX_IN_COUNT);
    }
}

五、生成重載函數(shù)

??Kotlin 的函數(shù)參數(shù)可以設(shè)置默認(rèn)值铝噩,看起來像多個(gè)函數(shù)重載一樣衡蚂。但 Java 中并不支持參數(shù)默認(rèn)值,只能支持全部參數(shù)函數(shù)骏庸。為了解決這個(gè)問題毛甲,可以在 Kotlin 函數(shù)前使用 @JvmOverloads 注解,Kotlin 編譯器會(huì)生成多個(gè)重載函數(shù)具被。@JvmOverloads 注解的函數(shù)可以是 構(gòu)造函數(shù)玻募、成員函數(shù)頂層函數(shù),但 不能是抽象函數(shù)一姿。

  • kotlin 示例代碼:
class Animal @JvmOverloads constructor(val age: Int, val sex: Boolean = false)

class DisplayOverloading {
    @JvmOverloads
    fun display(c: Char, num: Int = 1) {
        println("$c $num")
    }
}

@JvmOverloads
fun makeCoffee(type: String = "卡布奇諾"): String {
    return "制作一杯${type}咖啡"
}
  • IDE 解釋 Java 代碼:
public final class KotlinOverloadsKt {
   @JvmOverloads
   @NotNull
   public static final String makeCoffee(@NotNull String type) {
      Intrinsics.checkParameterIsNotNull(type, "type");
      return "制作一杯" + type + "咖啡";
   }

   // $FF: synthetic method
   @JvmOverloads
   @NotNull
   public static String makeCoffee$default(String var0, int var1, Object var2) {
      if ((var1 & 1) != 0) {
         var0 = "卡布奇諾";
      }

      return makeCoffee(var0);
   }

   @JvmOverloads
   @NotNull
   public static final String makeCoffee() {
      return makeCoffee$default((String)null, 1, (Object)null);
   }
}

// DisplayOverloading.java
public final class DisplayOverloading {
   @JvmOverloads
   public final void display(char c, int num) {
      String var3 = "" + c + ' ' + num;
      boolean var4 = false;
      System.out.println(var3);
   }

   // $FF: synthetic method
   @JvmOverloads
   public static void display$default(DisplayOverloading var0, char var1, int var2, int var3, Object var4) {
      if ((var3 & 2) != 0) {
         var2 = 1;
      }

      var0.display(var1, var2);
   }

   @JvmOverloads
   public final void display(char c) {
      display$default(this, c, 0, 2, (Object)null);
   }
}

// Animal.java
public final class Animal {
   private final int age;
   private final boolean sex;

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

   public final boolean getSex() {
      return this.sex;
   }

   @JvmOverloads
   public Animal(int age, boolean sex) {
      this.age = age;
      this.sex = sex;
   }

   // $FF: synthetic method
   @JvmOverloads
   public Animal(int var1, boolean var2, int var3, DefaultConstructorMarker var4) {
      if ((var3 & 2) != 0) {
         var2 = false;
      }

      this(var1, var2);
   }

   @JvmOverloads
   public Animal(int age) {
      this(age, false, 2, (DefaultConstructorMarker)null);
   }
}

??通過 IDE 解釋后七咧,可以看出 Kotlin 中的參數(shù)默認(rèn)值,在 Java 中實(shí)際是通過函數(shù)的重載來實(shí)現(xiàn)的叮叹。

  • Java 調(diào)用 Kotlin 含有默認(rèn)參數(shù)的函數(shù):
public class MainJava {

    public static void main(String[] args) {
        Animal animal1 = new Animal(10, true);
        Animal animal2 = new Animal(10);

        DisplayOverloading dis1 = new DisplayOverloading();
        dis1.display('A');
        dis1.display('B', 20);

        KotlinOverloadsKt.makeCoffee();
        KotlinOverloadsKt.makeCoffee("摩卡咖啡");
    }
}

注意:別忘了上面的 @file:JvmName("自定義名") 的使用艾栋。

六、異常檢查

??Kotlin 中沒有受檢查異常蛉顽,在函數(shù)后面也不會(huì)有異常聲明蝗砾。如果有如下的 Kotlin 代碼:

@file:JvmName("ErrorKt")

package cn.ak.kotmodule.kot

import java.text.SimpleDateFormat
import java.util.*

fun readDate(): Date? {
    val str = "201D-18-19"
    val df = SimpleDateFormat("yyyy-MM-dd") // 1??拋出異常
    // 從字符串中解析日期
    return df.parse(str)
}

??上面代碼第1??行會(huì)拋出 ParseException 異常,這是因?yàn)榻馕龅淖址皇且粋€(gè)合法的日期。在 Java 中 ParseException 是受檢查異常悼粮,如果在 Java 中調(diào)用 readDate 函數(shù)拇泣,由于 readDate 函數(shù)沒有聲明拋出 ParseException 異常,編譯器不會(huì)檢查要求 Java 程序捕獲異常處理矮锈。Java 調(diào)用代碼如下:

public class MainJava {

    public static void main(String[] args) {
        ErrorKt.readDate();
    }
}

??這樣處理異常不符合 Java 的習(xí)慣霉翔,為此可以在 Kotlin 的函數(shù)前加上 @Throw 注解,修改 Kotlin 代碼如下:

@Throws(ParseException::class)
fun readDate(): Date? {
    val str = "201D-18-19"
    val df = SimpleDateFormat("yyyy-MM-dd") // 拋出異常
    // 從字符串中解析日期
    return df.parse(str)
}

??注意在 readDate 函數(shù)前添加注解 @Throws(ParseException::class)苞笨,其中 ParseException 是需要處理的異常類债朵。
??那么 Java 代碼可以修改為如下捕獲異常形式:

public class MainJava {

    public static void main(String[] args) {
        try {
            ErrorKt.readDate();
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

??當(dāng)然在 Java 中除了 try-catch 捕獲異常,還可以聲明拋出異常瀑凝。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末序芦,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子粤咪,更是在濱河造成了極大的恐慌谚中,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寥枝,死亡現(xiàn)場(chǎng)離奇詭異宪塔,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)囊拜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門某筐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人冠跷,你說我怎么就攤上這事南誊。” “怎么了蜜托?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵抄囚,是天一觀的道長。 經(jīng)常有香客問我橄务,道長幔托,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任仪糖,我火速辦了婚禮柑司,結(jié)果婚禮上迫肖,老公的妹妹穿的比我還像新娘锅劝。我一直安慰自己,他們只是感情好蟆湖,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布故爵。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪诬垂。 梳的紋絲不亂的頭發(fā)上劲室,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音结窘,去河邊找鬼很洋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛隧枫,可吹牛的內(nèi)容都是我干的喉磁。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼官脓,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼协怒!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起卑笨,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤孕暇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后赤兴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體妖滔,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年桶良,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了铛楣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡艺普,死狀恐怖簸州,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情歧譬,我是刑警寧澤岸浑,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站瑰步,受9級(jí)特大地震影響矢洲,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜缩焦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一读虏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧袁滥,春花似錦盖桥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春塑荒,著一層夾襖步出監(jiān)牢的瞬間熄赡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來泰國打工齿税, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留彼硫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓凌箕,卻偏偏與公主長得像乌助,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子陌知,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Kotlin的類和接口與Java的類和接口是有一定的區(qū)別的仆葡。Kotlin的接口是可以包含屬性聲明赏参。Kotlin默認(rèn)...
    程自舟閱讀 10,338評(píng)論 0 11
  • 寫在開頭:本人打算開始寫一個(gè)Kotlin系列的教程把篓,一是使自己記憶和理解的更加深刻,二是可以分享給同樣想學(xué)習(xí)Kot...
    胡奚冰閱讀 1,422評(píng)論 5 11
  • 面向?qū)ο缶幊蹋∣OP) 在前面的章節(jié)中,我們學(xué)習(xí)了Kotlin的語言基礎(chǔ)知識(shí)窖铡、類型系統(tǒng)疗锐、集合類以及泛型相關(guān)的知識(shí)。...
    Tenderness4閱讀 4,441評(píng)論 1 6
  • Kotlin 調(diào)用 Java 由于 Kotlin本身并沒有提供強(qiáng)大的類庫支持费彼,Kotlin只是一種語言滑臊,因此 Ko...
    凌寒天下獨(dú)自舞閱讀 14,076評(píng)論 0 10
  • 近期抽時(shí)間看了幾篇短篇,這一年快過去了箍铲,或許真的寫不出和市場(chǎng)完全接軌的文章雇卷,在一切市場(chǎng)化的時(shí)代下,在閱讀多元化的多...
    綠竹君閱讀 204評(píng)論 0 1