Java教程

Kotlin学习之Kotlin和Java之间相互调用

本文主要是介绍Kotlin学习之Kotlin和Java之间相互调用,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Kotlin调用Java

调用普通类

public class Person {

  private String name;
  private boolean married;
  private int age;
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public boolean isMarried() {
    return married;
  }
  public void setMarried(boolean married) {
    this.married = married;
  }
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }
}

定义一个普通的Java类

fun main(args: Array<String>) {
    val person = Person()
    //修改属性
    person.name = "lisi"
    person.isMarried = true
    person.age = 30
    //访问属性
    println(person.name)
    println(person.isMarried)
    println(person.age)
}

可以看到,使用很简单

调用集合

import java.util.ArrayList

fun main(args: Array<String>) {
    val names = ArrayList<String>()
    names.add("lisi")
    names.add("王五")
    println(names)
}

调用可变参数

public class PersonService {
  public void saveUser(String... names) {
    for (String name : names) {
      System.out.println(name);
    }
  }
}

定义一个类,包含一个可变参数的方法

fun main(args: Array<String>) {
    val personService = PersonService()
    val names = arrayOf("lisi", "wangwu")
    //解构赋值
    personService.saveUser(*names)
    personService.saveUser("小明")
}

调用时如果传入数组,需要先解构(转换成多个变量)

获取对应的Java类型

fun main(args: Array<String>) {
    val personService = PersonService()
    println(personService::class.java)
    //这种方式更加简单
    println(personService.javaClass)
    println(12.javaClass)
}

Java调用Kotlin

自定义Class名称

package com.imooc.kotlin_first.study

fun saveUser(username: String) {
    println(username)
}

定义一个kotlin文件UserService.kt,编译之后生成的Class为UserServiceKt.class,我们也可以自定义Class名称

@file:JvmName("UserService")
@file:JvmMultifileClass
package com.imooc.kotlin_first.study

fun saveUser(username: String) {
    println(username)
}

使用JvmName注解自定义Class名称,使用JvmMultifileClass注解可以将多个kotlin文件(JvmName注解提供的名称一样)编译到一个Class中

public class Client {
  public static void main(String[] args) {
    UserService.saveUser("lisi");
  }
}

自定义属性

class Person {
    var name: String = "lisi"
}

定义一个普通kotlin类,编译之后,属性默认为private,且会生成getter和setter。

public class Client {
  public static void main(String[] args) {
    Person person = new Person();
    person.setName("lisi");
    System.out.println(person.getName());
  }
}
class Person {
    @JvmField
    var name: String = "lisi"
}

JvmField注解表示编译器不生成getter和setter,且属性为public。

静态属性和方法

class Person {
    companion object {
        @JvmField
        val name: String = "lisi"
        val age: Int = 20
        @JvmStatic
        fun test() {}
        fun test2() {}
    }
}

JvmField注解和JvmStatic注解将属性和方法标记为静态属性和静态方法

public class Client {
  public static void main(String[] args) {
    System.out.println(Person.name);
    Person.test();
    System.out.println(Person.Companion.getAge());
    Person.Companion.test2();
  }
}

反编译结果为

点击查看代码
public final class Person {
   @JvmField
   @NotNull
   public static final String name = "lisi";
   private static final int age = 20;
   public static final Person.Companion Companion = new Person.Companion((DefaultConstructorMarker)null);

   @JvmStatic
   public static final void test() {
      Companion.test();
   }

   public static final class Companion {
      public final int getAge() {
         return Person.age;
      }

      @JvmStatic
      public final void test() {
      }

      public final void test2() {
      }

      private Companion() {
      }

      // $FF: synthetic method
      public Companion(DefaultConstructorMarker $constructor_marker) {
         this();
      }
   }
}

调用包含默认参数的方法

class Person {
    fun test(age: Int = 20) {
    }
    @JvmOverloads
    fun test2(age: Int = 20) {
    }
}

JvmOverloads注解会生成一个不包含参数的重载方法,底层也是调用有参的那个方法

public class Client {
  public static void main(String[] args) {
    Person person = new Person();
    person.test(21);
    person.test2();   //重载方法
    person.test2(22); 
  }
}

反编译结果为

点击查看代码
public final class Person {
   public final void test(int age) {
   }

   // $FF: synthetic method
   public static void test$default(Person var0, int var1, int var2, Object var3) {
      if ((var2 & 1) != 0) {
         var1 = 20;
      }

      var0.test(var1);
   }

   @JvmOverloads
   public final void test2(int age) {
   }

   // $FF: synthetic method
   @JvmOverloads
   public static void test2$default(Person var0, int var1, int var2, Object var3) {
      if ((var2 & 1) != 0) {
         var1 = 20;
      }

      var0.test2(var1);
   }

   @JvmOverloads
   public final void test2() {
      test2$default(this, 0, 1, (Object)null);
   }
}

抛出异常

kotlin中没有受检异常(非运行时异常)

import java.io.FileNotFoundException

class Person {
    fun test() {
        throw FileNotFoundException("Not Found")
    }
}

定义一个方法,抛出异常,可以看到,不需要在方法声明时抛出异常,反编译结果为

public final class Person {
   public final void test() {
      throw (Throwable)(new FileNotFoundException("Not Found"));
   }
}
public class Client {
  public static void main(String[] args) {
    Person person = new Person();
    person.test();
  }
}

java调用此方法就会在运行时抛出异常。

class Person {
    @Throws(FileNotFoundException::class)
    fun test() {
        throw FileNotFoundException("Not Found")
    }
}

通过Throws注解显式声明抛出异常,反编译结果为

public final class Person {
   public final void test() throws FileNotFoundException {
      throw (Throwable)(new FileNotFoundException("Not Found"));
   }
}

非空检查

class Person {
    fun test(str: String) {
    }
}

kotlin中参数和变量默认都是不能为null的,除非显式声明为[类型]?,反编译结果为

public final class Person {
   public final void test(@NotNull String str) {
      // 检查是否为null
      Intrinsics.checkParameterIsNotNull(str, "str");
   }
}
public class Client {
  public static void main(String[] args) {
    Person person = new Person();
    person.test("abc");
    person.test(null);//抛出异常
  }
}
这篇关于Kotlin学习之Kotlin和Java之间相互调用的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!