博主前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住也分享一下给大家
点击跳转到教程
一、Kotlin与Java互操作与可空性。
Kotlin与Java互操作性与可空性
Java世界里所有对象都可能是null,当一个Kotlin函数返回String类型值,你不能想当然地认为
它的返回值就能符合Kotlin关于空值的规定。
1、首先定义一个Java类
public class Jhava {
public String utterGreeting() {
return "hello";
}
public String determineFriendshipLevel() {
return null;
}
}
2、Kotlin代码调用Java代码
fun main() {
/**
* Kotlin与Java互操作性与可空性
* Java世界里所有对象都可能是null,当一个Kotlin函数返回String类型值,你不能想当然地认为
* 它的返回值就能符合Kotlin关于空值的规定。
*/
val adversary = Jhava()
println(adversary.utterGreeting())
/**
* 返回 String! 类型的值,这里的感叹号表示返回值是String或者String?
* 至于Java方法返回的是String类型值是null还是其他什么,Kotlin编译器并不知道。
* 这种模棱两可的返回值类型,我们称之为平台类型。
*/
var level = adversary.determineFriendshipLevel()
/**
* null值问题最有可能来自互操作,所以从kotlin里调用Java代码时,一定要小心谨慎。
*/
println(level?.toLowerCase())
}
输出结果如下
hello
null
二、类型映射、属性访问、@JvmOverloads详解
public class Jhava {
private int age = 18;
public int num = 1;
public String utterGreeting() {
return "hello";
}
public String determineFriendshipLevel() {
return null;
}
public int getAge() {
System.out.println("------getAge()-----");
return age;
}
public void setAge(int age) {
this.age = age;
}
public static void main(String[] args) {
/**
* Kotlin顶层函数在Java里都被当作静态方法看待和调用。
*/
System.out.println(Hero.makeProclamation());
Spellbook spellbook = new Spellbook();
List<String> spells = spellbook.spells;
System.out.println(spells);
/**
* Java要支持
*/
Hero.handOverFood("apple");
}
}
/**
* 可以使用@JvmName注解指定编译类的名字。
* 必须放在包名上面,否则报错。
*/
@file:JvmName("Hero")
package com.example.kotlinlearn.kotlin06
/**
* @Author: ly
* @Date: 2023/2/8
* @Description:
*/
fun main() {
val adversary = Jhava()
/**
* 代码运行时,所有的映射类型都会重新映射成对应的Java类型
*/
println(adversary.num.javaClass)
/**
* 属性访问
* 不需要调用相关setter方法,你可以使用赋值语法来设置一个Java字段值。
*/
println(adversary.age)
adversary.age = 40
println(adversary.age)
handOverFood("apple")
}
fun makeProclamation() = "Greeting,best!"
/**
* @JvmOverloads 注解协助产生Kotlin函数的重载版本。设计一个可能会暴露给Java用户使用API时,记得使用
* @JvmOverloads 注解,这样,无论你是Kotlin开发者还是Java开发者,都会对这个API的可靠性感到满意。
*/
@JvmOverloads
fun handOverFood(leftHand: String = "berries", rightHand: String = "beef") {
println("Mmm you hand over some delicious $leftHand and $rightHand")
}
输出结果如下
int
------getAge()-----
18
------getAge()-----
40
Mmm you hand over some delicious apple and beef
三、@JvmField详解
1、使用Kotlin创建一个类
class Spellbook {
/**
* 在Java里,不能直接访问spells字段,所以必须调用getSpells,然而,你可以给
* Kotlin属性添加@JvmField注解,暴露它的支持字段给Java调用者,从而避免用getter方法。
*/
@JvmField
val spells = listOf("Magic Ms.L", "Lay on Hans")
}
2、使用Java创建一个Person类
public class Person{
public static void main(String[] args) {
Spellbook spellbook = new Spellbook();
List<String> spells = spellbook.spells;
System.out.println(spells);
}
}
输出结果如下
[Magic Ms.L, Lay on Hans]
四、@JvmStatic、@Throws和函数类型操作
class Student {
companion object {
/**
* @JvmField 注解还能用来以静态方式提供伴生对象来定义的值。
*/
@JvmField
val STUDENT_NAME = "Android"
/**
* @JvmStatic 注解的作用类似于@JvmField,允许你直接调用伴生对象里的函数。
*/
@JvmStatic
fun study() = "I am study Android development"
}
}
fun main() {
//Kotlin中所有的异常都是默认不捕获的,当然也可以手动添加try catch进行捕获
// Grade().doSomething()
try {
Grade().doSomething()
} catch (e: Exception) {
println("Java IOException")
}
println("测试")
ktExceptionMethod()
}
/**
* @Throws
* 抛出一个需要检查的异常,Java和Kotlin有关异常检查的差异让@Throws注解给解决掉了,
* 在编写供Java开发者调用的KotlinAPI时,要考虑使用@Throws注解,这样用户就知道怎么正确处理异常了。
*/
@Throws(IOException::class)
fun ktExceptionMethod() {
throw IOException()
}
val major = { majorName: String, majorContent: String ->
println("$majorName study $majorContent")
}
输出结果如下
Java IOException
测试
Exception in thread "main" java.io.IOException
at com.example.kotlinlearn.kotlin06.StudentKt.ktExceptionMethod(Student.kt:47)
at com.example.kotlinlearn.kotlin06.StudentKt.main(Student.kt:37)
at com.example.kotlinlearn.kotlin06.StudentKt.main(Student.kt)
Java类如下
public class Grade {
public static void main(String[] args) {
System.out.println(Student.STUDENT_NAME);
System.out.println(Student.study());
try {
new Grade().doSomething();
} catch (IOException e) {
System.out.println("IOException");
}
System.out.println("test");
try {
StudentKt.ktExceptionMethod();
} catch (IOException e) {
System.out.println("kotlin exception");
}
/**
* 函数类型和匿名函数能提供高效的语法用于组件间的交互,是Kotlin编程语言里比较新颖的特性。
* 它们简洁的语法因->操作符而实现,但Java8之前的JDK版本并不支持lambda表达式。
* 在Java里,Kotlin函数类型使用FunctionN这样的名字的接口来表示的,FunctionN中的N代表值参数目。
* 这样的Function接口有23个,从Function0到Function22,每一个FunctionN都包含一个invoke函数,专用于
* 调用函数类型函数,所以,任何时候需要调一个函数类型,都要它调用invoke()方法。
*/
Function2<String, String, Unit> major = StudentKt.getMajor();
major.invoke("computer", "Knock the code");
}
public void doSomething() throws IOException {
throw new IOException();
}
}
输出结果如下
Android
I am study Android development
IOException
test
kotlin exception
computer study Knock the code