ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 1. 前言 | 符号 | 说明 | | --- | --- | | `@JvmName` | 指定`kotlin`编译类的名字 | | `@JvmField` | 指定可直接访问类的属性,而不是`getXX`或者`setXX`方法 | | `@JvmOverloads` | 指定重载`Kotlin`的默认参数方法 | | `@JvmStatic` | 指定`Kotlin`的半生对象的静态方法的直接点好调用 | | `@Throws` | 指定抛出的异常类型 | # 2. 使用案例 ## 2.1 @JvmName 新建一个`KotlinDemo.kt`文件,然后写入一个供外部`Java`程序调用的方法: ~~~ package com.kotlinLearn fun isPrime(number: Int): Boolean { (2 until number).map { if(number % it == 0) return false } return true } ~~~ 我们就可以在`A.java`文件中进行调用,比如: ~~~ package com.kotlinLearn; public class A { public static void main(String[] args) { boolean prime = KotlinDemoKt.isPrime(4); System.out.println(prime ? "素数" : "非素数"); } } ~~~ 结果: ``` 非素数 ``` 虽然可以实现调用,但是我们需要暴露自己的`kotlin`文件名,所以这里可以使用`JvmName`来进行重命名: ~~~ @file:JvmName("MyUtils") package com.kotlinLearn fun isPrime(number: Int): Boolean { (2 until number).map { if(number % it == 0) return false } return true } ~~~ 对应的我们在调用的时候,所使用的就是: ~~~ boolean prime = MyUtils.isPrime(4); ~~~ ## 2.2 @JvmField 类似的我们在`KotlinDemo.kt`文件中定义一个类: ~~~ class User{ var name: String? = null } ~~~ 然后在`A.java`文件中调用,可以看见下图: ![](https://img.kancloud.cn/b9/50/b9506a3054805f392183ebf023fbf4b7_789x220.png) 也就是说其实默认的调用可以使用`get`和`set`来获取到在`kotlin`中的属性,但是有些时候我们期望可以直接访问到属性,而不是`get`或者`set`方法。那么就可以使用`@JvmField`来实现: ~~~ @file:JvmName("MyUtils") package com.kotlinLearn class User{ @JvmField var name: String? = null } ~~~ 然后在`A.java`中调用: ~~~ user.name = "李四"; ~~~ ## 2.3 @JvmField 在`Kotlin`和`Python`中使用类似,我们可以定义一些默认参数,然后可以有默认的实现效果。比如: ~~~ @file:JvmName("MyUtils") package com.kotlinLearn class User(@JvmField var name: String, @JvmField var age: Int) { override fun toString(): String { return "User(name='$name', age=$age)" } } fun generateUser(name: String = "张三", age: Int = 23): User{ return User(name, age) } fun main() { val user = generateUser() println(user) } ~~~ 结果: ``` User(name='张三', age=23) ``` 同样的,我们在`A.java`中调用: ~~~ package com.kotlinLearn; public class A { public static void main(String[] args) { User user = MyUtils.generateUser("李四", 23); System.out.println(user); } } ~~~ 但是,由于在`Java`中默认并不支持,所以我们定义默认参数其实底层就是函数重载,比如: ~~~ public User generateUser(String name, int age){ return new User(name, age); } public User generateUser(String name){ return generateUser(name, 23); } public User generateUser(int age){ return generateUser("张三", age); } public User generateUser(){ return generateUser("张三", 23); } ~~~ 但是确实写起来比较麻烦。所以在`Java`调用`Kotlin`中含有默认的参数的时候,可以使用`@JvmOverloads`关键字实现,比如: ~~~ @JvmOverloads fun generateUser(name: String = "张三", age: Int = 23): User{ return User(name, age) } ~~~ 调用: ~~~ public class A { public static void main(String[] args) { User user = MyUtils.generateUser("李四"); System.out.println(user); } } ~~~ ## 2.4 @JvmStatic 在`Kotlin`中不再有静态属性和方法,对应的是一个伴生对象。比如下面的案例: ~~~ class User(@JvmField var name: String, @JvmField var age: Int) { override fun toString(): String { return "User(name='$name', age=$age)" } // 定义伴生对象 companion object { var UUID: String = "1231232" fun getUUID() = println(UUID) } } ~~~ 然后在`kotlin`中调用: ~~~ fun main() { // 和Java中静态类似,可以直接通过类来访问 User.Companion.getUUID() User.getUUID() } ~~~ 不妨继续在`A.java`文件中进行调用: ~~~ public class A { public static void main(String[] args) { // 通过@JvmField转为可以直接调用 System.out.println(User.UUID); // 调用方法 User.Companion.getUUID(); // 通过@JvmStatic将方法转为可直接调用 User.getUUID(); } } ~~~ 当然,对应的`Kotlin`的代码中添加了两个注解: ~~~ // 定义伴生对象 companion object { @JvmField var UUID: String = "1231232" @JvmStatic fun getUUID() = println(UUID) } ~~~ 需要注意的是,在伴生对象中对属性和方法分别使用`@JvmField`和`@JvmStatic`两个关键字。 ## 2.5 @Throws ~~~ // 定义:该方法抛出一个IO异常 fun getUser(){ throw IOException() } ~~~ 然后在`Java`中调用: ~~~ public class A { public static void main(String[] args) { // 调用异常 MyUtils.getUser(); } } ~~~ 但是代码没有提示需要使用`try-catch`来对异常进行捕获,运行: ``` Exception in thread "main" java.io.IOException at com.kotlinLearn.MyUtils.getUser(KotlinDemo.kt:34) at com.kotlinLearn.A.main(A.java:6) ``` 所以可以添加一个`@Throws`注解进行说明: ~~~ // 定义:该方法抛出一个IO异常 @Throws(IOException::class) fun getUser(){ throw IOException() } ~~~ 然后调用的时候就会有对应的异常提示,如下图: ![](https://img.kancloud.cn/05/17/0517243d18b945ea96ae0720fbf2e676_649x199.png)