本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点
互操作性和可空性
- 要注意Java中所有类型都是可空的
- String!表示平台数据类型
public class JavaTest {
public String generateName() {
return "name";
}
//可以用注解标注可空
@Nullable
public String generateNullString() {
return null;
}
}
fun main() {
val result = JavaTest()
//要用安全操作符来操作
println(result?.generateName())
}
类型映射
- kotlin代码运行时,所有的映射类型都会重新映射回对应得Java类型
属性访问
- 不需要调用相关setter和getter方法,可以用赋值语法来设置一个Java字段值
fun main() {
val result = JavaTest()
println(result.generateNullString())
//对应的Java类中属性要实现get和set方法
println(result.points)
}
@JvmName
- 用来注解指定编译类的名字,方便Java调用
//System.out.printf(HeroKt.sayHello());
//用JvmName改了名字后
System.out.printf(Hero.sayHello());
@JvmField
用@JvmField修饰后,Java中可以直接调用属性,不用getter方法
class SpellBook {
@JvmField
val spells = "hello world"
}
public class JHaa {
public static void main(String[] args) {
SpellBook spellBook = new SpellBook();
//没有@JvmField修饰时的调用方法
// spellBook.getSpells();
System.out.printf(spellBook.spells);
}
}
@JvmOverloads
- 协助产生kotlin函数的重载版本,设计一个可能会暴露给Java用户使用的API,记得使用 @JvmOverloads注解
class SpellBook {
@JvmField
val spells = "hello world"
@JvmOverloads
fun handleWithDefault(left:String = "left", right:String = "right"){
println("you handle with $left and $right")
}
}
public class JHaa {
public static void main(String[] args) {
SpellBook spellBook = new SpellBook();
// spellBook.getSpells();
System.out.printf(spellBook.spells);
//没有JvmOverloads注解时会报错,因为没有这个无参的重载函数版本
spellBook.handleWithDefault();
}
}
@JvmStatic
- @JvmField注解还能用来以静态方式提供伴生对象里定义的值
- @JvmStatic注解的作用类似于@JvmField,允许你直接调用伴生对象的函数
//互操作
class SpellBook {
@JvmField
val spells = "hello world"
@JvmOverloads
fun handleWithDefault(left:String = "left", right:String = "right"){
println("you handle with $left and $right")
}
companion object{
@JvmField
val MAX_SPELL_COUNT = 10
@JvmStatic
fun getSpell() = println("i am groot!")
}
}
public class JHaa {
public static void main(String[] args) {
SpellBook spellBook = new SpellBook();
//伴生对象属性的调用方式
// spellBook.Companion.getMAX_SPELL_COUNT();
//伴生对象的属性加了@JvmField修饰以后
int result = spellBook.MAX_SPELL_COUNT;
spellBook.Companion.getSpell();
//加了@JvmStatic修饰以后
spellBook.getSpell();
}
}
@Throws
- 抛出一个需要检查的指定异常,Java和kotlin有关的异常检查的差异让@Throws注解解决了,在编写供Java开发者调用的Kotlin API时,要考虑使用@Throws注解。这样用户就指定怎么正确处理任何异常了
- kotlin中抛出的异常会被转换成Throwable,Java中会catch不了。加上@Throws注解就可以在Java中正常catch
class SpellBook {
@Throws(IOException::class)
fun funWithException() {
throw IOException()
}
}
public class JHaa {
public static void main(String[] args) {
SpellBook spellBook = new SpellBook();
try {
spellBook.funWithException();
//没有Throws时,这里只能是Throwable,编译器也不会提示
} catch (IOException e) {
e.printStackTrace();
}
}
}
函数类型操作
- kotlin函数类型和匿名函数的简洁高效的语法因->操作符而实现,但Java8之前的JDK版本不支持lambda表达式。
- 在Java里,kotlin函数类型使用FuctionN这样的名字的接口来表示,N代表值参的数目,这样的Function接口由23个,每一个都包含一个invoke函数,专门用于调用函数类型函数
class SpellBook {
val translator = { origin:String ->
println(origin.lowercase().capitalize())
}
}
public class JHaa {
public static void main(String[] args) {
SpellBook spellBook = new SpellBook();
Function1<String, Unit> translator = spellBook.getTranslator();
translator.invoke("TRACE");
}
欢迎关注我的公众号查看更多精彩文章!