boolean isFlag
可以作为Kotlin的只读属性,该属性名为isFlag
如果java方法的返回值是void,在Kotlin中对应于Unit返回值类型。如果有人使用其返回值,它将由 Kotlin 编译器在调用处赋值, 因为该值本身是预先知道的(是 Unit
)。
Kotlin的关键字比java多,很多关键字在java中并不是关键字,所以可能出现java的类、接口名、方法名是Kotlin关键字的情况,此时需要加反引号对关键字进行转译
java类
public class User {
private String userName;
private boolean isMarried;
protected int age;
public void in() {
System.out.println("in run...");
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public boolean isMarried() {
return isMarried;
}
public void setMarried(boolean married) {
isMarried = married;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
kotlin中调用
fun main(args: Array<String>) {
val user = User()
user.userName = "jannal"
user.isMarried = true
println(user.userName)
println(user.isMarried)
//in在kotlin中是关键字,所以在kotlin中需要调用in()需要转译(``)
user.`in`();
}
Kotlin为java部分类提供了一些处理,这部分java类被映射为Kotlin类,这种映射只在编译阶段发生,运行时还是java类型。这些 Java 类型的静态成员不能在相应 Kotlin 类型的伴生对象中直接访问。要调用它们,请使用 Java 类型的完整限定名,例如 java.lang.Integer.toHexString(foo)
Java 的原生类型映射到相应的 Kotlin 类型
Java 类型 | Kotlin 类型 |
---|---|
byte | kotlin.Byte |
short | kotlin.Short |
int | kotlin.Int |
long | kotlin.Long |
char | kotlin.Char |
float | kotlin.Float |
double | kotlin.Double |
boolean | kotlin.Boolean |
Java 的装箱原始类型映射到可空的 Kotlin 类型。用作类型参数的装箱原始类型映射到平台类型, 例如,List<java.lang.Integer>
在 Kotlin 中会成为 List<Int!>
。
Java 类型 | Kotlin 类型 |
---|---|
java.lang.Byte | kotlin.Byte? |
java.lang.Short | kotlin.Short? |
java.lang.Integer | kotlin.Int? |
java.lang.Long | kotlin.Long? |
java.lang.Character | kotlin.Char? |
java.lang.Float | kotlin.Float? |
java.lang.Double | kotlin.Double? |
java.lang.Boolean | kotlin.Boolean? |
非原生的内置类型
java.lang.Object | kotlin.Any! |
---|---|
java.lang.Cloneable | kotlin.Cloneable! |
java.lang.Comparable | kotlin.Comparable! |
java.lang.Enum | kotlin.Enum! |
java.lang.Annotation | kotlin.Annotation! |
java.lang.CharSequence | kotlin.CharSequence! |
java.lang.String | kotlin.String! |
java.lang.Number | kotlin.Number! |
java.lang.Throwable | kotlin.Throwable! |
集合类型:集合类型在 Kotlin 中可以是只读的或可变的
Java 类型 | Kotlin 只读类型 | Kotlin 可变类型 | 加载的平台类型 |
---|---|---|---|
Iterator<T> | Iterator<T> | MutableIterator<T> | (Mutable)Iterator<T>! |
Iterable<T> | Iterable<T> | MutableIterable<T> | (Mutable)Iterable<T>! |
Collection<T> | Collection<T> | MutableCollection<T> | (Mutable)Collection<T>! |
Set<T> | Set<T> | MutableSet<T> | (Mutable)Set<T>! |
List<T> | List<T> | MutableList<T> | (Mutable)List<T>! |
ListIterator<T> | ListIterator<T> | MutableListIterator<T> | (Mutable)ListIterator<T>! |
Map<K, V> | Map<K, V> | MutableMap<K, V> | (Mutable)Map<K, V>! |
Map.Entry<K, V> | Map.Entry<K, V> | MutableMap.MutableEntry<K,V> | (Mutable)Map.(Mutable)Entry<K, V>! |
数组类型映射,kotlin的数组是不型变的,即Array不能赋值给Array,这与java是不同的,java的String[]可以直接赋值给Obejct[]变量,但是java这种方式很容易导致异常。
Java 类型 | Kotlin 类型 |
---|---|
int[] | kotlin.IntArray! |
String[] | kotlin.Array<(out) String>! |
泛型转换
Java 类型 | Kotlin 类型 |
---|---|
Foo<? extends Bar> | Foo<out Bar!>! |
Foo<? super Bar> | Foo<in Bar!>! |
Foo<*> | Foo<out Any?>! |
Foo | Foo<*> |
kotlin与java一样泛型都会在编译后擦除,即运行时无法保留泛型信息,所以kotlin中使用is进行类型检测时只能检测星号
val list = listOf<Int?>(1,2,3)
// list is List<Int>
list is List<*>
对于可变参数,java中可以直接传入一个数组,但是kotlin不行。kotlin要求只能传入多个参数值,但也可通过使用**"*"**解开数组的方式来传入多个数组元素作为参数值
java代码
public class JavaVarargs {
public void info(int... nums) {
for (int i = 0; i < nums.length; i++) {
System.out.println(nums[i]);
}
}
}
kotlin代码
fun main() {
var jv = JavaVarargs()
jv.info(2, 3, 4)
var intArr = intArrayOf(2, 3, 4)
jv.info(*intArr)
}
java的java.lang.Object对应Kotlin的Any,因为Any只有toString()、hashcode()、equals(),所以需要考虑Object有但是Any没有的方法
如果程序中需要调用wait()/notify()/notifyAll(),可以在程序中将Any强制转换为Object
(foo as java.lang.Object).wait()
getClass (),在kotlin通过如下方式
obj::class.java
obj.javaClass
clone(),在kotlin中实现kotlin.Cloneable
接口即可
finalize(),在kotlin直接写此方法,不需要override关键字(因为Any中没有此方法),finalize不能定义为private
class Foo{
protected fun finalize(){
}
}
访问静态成员,kotlin通过伴生对象的语法来访问
java代码
public class User {
public static final String STATUS = "1";
public static void info(){
System.out.println("静态方法info");
}
}
kotlin代码
fun main(args: Array<String>) {
User.info()
User.STATUS
}
java8支持使用Lambda表达式来作为函数式接口的实例(这种机制称为SAM转换),SAM 是Single Abstract Method是缩写,SAM转换的条件:Java的接口,只有一个接口当参数的方法,可以使用lambda当参数
java代码
public class SAMInJava {
private ArrayList<Runnable> runnables = new ArrayList<Runnable>();
public void addTask(Runnable runnable) {
runnables.add(runnable);
System.out.println("添加:" + runnable + "任务之后,一共有" + runnables.size() + "个任务");
}
public void removeTask(Runnable runnable) {
runnables.remove(runnable);
System.out.println("删除:" + runnable + "任务之后,一共有" + runnables.size() + "个任务");
}
}
kotlin代码
/**
* kotlin本身不支持将只有runnable接口当参数的方法直接以lambda方式使用,
* 但使用typealias关键词给Runnable起别名之后(相当于() -> Unit就是Runnable),
* 就可以以lambda方式使用
*/
typealias Runnable = () -> Unit
class SAMInKotlin {
fun addTask(runnable: Runnable) {
}
}
kotlin调用java代码
/**
* kotlin与java互操作(SAM 转换)
* 1.对于实现了kotlin实现的java接口,在java函数中定义该参数后,kotlin引用时可以用lambda表达式使用
* 2.由于java与kotlin表达式并不兼容,所以在每次添加lambda表达式都不是同一个对象
*/
fun main(args: Array<String>) {
val samInJava = SAMInJava() //实例化java中的类
//lambda调用方法1:使用java中的带kotlin已支持的接口参数的方法,可以直接使用lambda表达式当参数
samInJava.addTask {
println("Hello")
}
val lambda = {
println("World")
}
//lambda调用方法2
samInJava.addTask(lambda)
samInJava.addTask(lambda)
samInJava.addTask(lambda)
samInJava.addTask(lambda)
samInJava.removeTask(lambda)
samInJava.removeTask(lambda)
samInJava.removeTask(lambda)
samInJava.removeTask(lambda)
val samInKotlin = SAMInKotlin() //实例化kotlin中的类
//以lambda表达式使用kotlin中的方法
samInKotlin.addTask {
println("haha")
}
}
在java中使用JNI,需要使用native方法,表示该方法将会交给平台本地代码实现
在kotlin中使用external,函数不能有函数体
external fun foo(x: Int):Double