Kotlin中与Java互操作与可空性、类型映射、属性访问、@JvmOverloads、@JvmField、@JvmStatic、@Throws和函数类型操作详解

一、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

文章来源于互联网:Kotlin中与Java互操作与可空性、类型映射、属性访问、@JvmOverloads、@JvmField、@JvmStatic、@Throws和函数类型操作详解

阅读全文
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/archives/19789,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?