原文在 https://github.com/Zhuinden/guide-to-kotlin
kotlin语言语法的不同
参照java对kotlin语言进行学习,对一些概念进行类比。
常识不同(参数和类型的顺序,void = unit,Object = Any?, fun等):
- 定义函数使用fun
- 定义参数 name: type
- 定义返回参数 fun funName(paramName:type) : type {}. 例子如下:
fun matches(b: ByteArray): Boolean{
return false;
}
- void 返回值在kotlin中是不需要显示写出来的,如果一定要显示写出来,就使用unit
- @Override 要改成override,且是强制性的,必需显示写出来,java中不需要显示写出来。
- 使用Any?替代Object类型
- 没有new关键字
public abstract class BaseClass{
//...
}
public class MyClass extends BaseClass{
private final Map<String, Object> objects = new HashMap<>();
public MyClass(){}
@Override
public void addToMap(String key, Ojbect value){
objects.put(key, value);
}
}
final MyClass myClass = new MyClass();
对应的kotlin代码如下
abstract class BaseClass{}
class MyClass : BaseClass(){
private val objects = hashMapOf<String, Any?>()
init {
}
ovveride fun addToMap(key: String, value: Any?){
objects.put(key, value);
}
fun <T> getObject(key: String): T =
objects.get(key) as T
}
val myClass = MyClass()
接口和val,var还有fun
在kotlin中val和var的区别很重要:
- var表示变量
- val表示一个final修饰的变量。
- 每一个var修饰的变量默认暴露getter/setter。 val修饰的只暴露了getter。
interface MyContract {
var value: String
val name: String
fun doSomething(input1: String, input2: String)
}
class MyImpl(
override var value: String,
override val name: String
): MyContract {
override fun doSomething(input1: String, input2: String) {
...
}
}
构造函数和继承
如下,kotlin可以传递参数给supper-constructors,跟java中的super(param)一样。
class MyClass(
tag: String,
private val name: String,
var mutableField: String = "" // default argument
): BaseClass(tag), MyInterface {
override fun methodFromInterface() {
}
}
class MyCustomView : FrameLayout {
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, @AttrRes defStyleAttr: Int) : super(context, attrs, defStyleAttr)
kotlin中可以使用constructor关键字
lateinit vars
enum
java中使用 enum ClassName{}
kotlin定义方式 enum class ClassName{}
注解
java中定义一个注解是 public @interface MyAnnotation{}
kotlin定义为 annotation class
final 和open
任何class默认都是final修饰,意味着不能继承,如果要继承一个kotlin类,那么要使用open修饰
open class SomeClass{}
循环
for(i in 0 until n){}
for(pair in pairs){
}
for((key, value) in map.entries){
}
单例
object MySingleton{
fun doSomething(){
}
}
Mysingleton.doSomething()
object NetWork{
const val API_URL = "http://www.baidu.com"
const val TIMEOUT = 1000
}
object Positions {
@JvmStatic
fun create(x: Int, y: Int): Int = Position(x, y)
// ...
}
伴生对象实现静态方法, 常量
在kotlin中没有static关键字,但是kotlin中有伴生对象的概念—companion object,使用伴生对象来实现静态变量和静态方法。
class MyClassWithStatics {
companion object {
const val SOME_CONSTANT = "Hello!"
@JvmField var someUglyMutableField: String = "don't do this like ever"
@JvmStatic fun hello() { println("$SOME_CONSTANT $someUglyMutableField") }
}
}
// consuming Java code!
public class MyOtherClass {
public void doSomething() {
String constant = MyClassWithStatics.SOME_CONSTANT;
String someUglyMutableField = MyClassWithStatics.someUglyMutableField;
MyClassWithStatics.hello();
}
}
为什么要使用 JvmField JvmStatic注解,如果不使用,那么在java端的使用样例如下:
public class MyOtherClass {
public void doSomething() {
String constant = MyClassWithStatics.Companion.INSTANCE.SOME_CONSTANT;
String someUglyMutableField = MyClassWithStatics.Companion.INSTANCE.someUglyMutableField;
MyClassWithStatics.Companion.INSTANCE.hello();
}
}
可见性
在java中 有 private , package protected public
在kotlin中有private , protected public(default) internal
需要注意的是 internal不是package
在kotlin中没有package这个可见性。
static修饰的内部类和kotlin中的inner
在kotlin中,内嵌类默认就等同于java中的 public static class,所以定义一个内部类,需要明确使用inner修饰. 内部类会引用外部类对象,而内嵌类不会。
倒引号的使用
在kotlin中调用java类库中的代码,有可能类库中的方法是kotlin的关键字,这时候需要使用倒引号
Mockito.`when`(text.hashCode())
kotlin中的 is和as as?
java中判断一个对象是否是某类型使用 instanceof, 而kotlin中使用is。
kotlin使用as 和as? 来进行强制类型转换
class Cat(private val name: String) {
fun meow() {
println("The cat $name meowed.")
}
}
fun doSomething(obj: Any?) {
if(obj is Cat) {
obj.meow() // note that as `obj` is a `val`, the cast is automatic here
}
}
强制类型转换的时候,我们不能确定时候,在kotlin中就可以使用as?,如果使用as 强制转型失败就会抛异常,而as?不会,返回的是null
(obj as? Cat)?.meow()
匿名实现类和接口
myView.setOnClickListener(object: View.OnClickListener{
override fun onClick(view: View){
//do something
}
})
myView.setOnClickListener((view) -> {
//do something
})
myView.setOnClickListener{view ->
//do something
}
kotlin中没有三元运算符
可以使用如下来代替
val something = if() ... else ...
val something = when {
value != "hello" -> "beep"
else -> "boop"
}
单行函数可以使用=代替return
fun getRepository(): Repository = repository
fun getRepository(): Repository {
return repository
}
arrayOf / arrayOfNulls / listOf / mutableListOf / linkedMapOf
private final List<String> strings = new ArrayList<>();
private val strings = arrayListOf<String>()
val squares = List(size = 6) { index -> index * index}
//same as
val squares = ListOf(0, 1, 4, 9, 16, 25)
volatile 和@Volatile
多泛型边界
public class MyClass<T extends SomeClass & Comparable> {
...
}
class MyClass<T: SomeClass> { // this would be single-bounds
class MyClass<T>
where T: SomeClass,
T: Comparable { // multiple generic bounds