kotlin实践


Apple.kt
val fun(name:String) {
println(name)
}
in kotlin
Apple.fun()
in java
AppleKt.fun()


object关键词声明同时是单例的写法:
object Apple {
fun echo(name:String) {
println(name)
}
}
in kotlin
Apple.echo()
in java
Apple.INSTANCE.echo()


kotlin中class作为参数的写法
fun main(args: Array<String>) {
test(JavaObject::class.java)
test(KotlinObject::class)
}
fun test(clazz: Class<JavaObject>) {
println(clazz.simpleName)
}
fun test(clazz: KClass<KotlinObject>) {
println(clazz.simpleName)
}


java中的in变量在kotlin中是关键字
public class JavaObject {
public static final String in = “int”;
}
调用:
println(JavaObject.in)


kotlin是没有封装类的,比如Integer
如何通过反射去调用Integer类型

在调用java代码的时候,在不确定是否是非空且安全的,一定要声明成可空安全的类型,如string? string?.length
假设两种情况 :string :string! (兼容类型,暂时存在),就会导致报错


用注解@jvmStatic,修饰类成员方法,可以让调用简化:
如:
object Test {
@jvmStatic
fun test() {
}
}

Test.test(),
假设不加注解@jvmStatic,调用就是Test.Instance.test()


函数
1 .函数可以省略{} 写在fun函数后面
fun getName(name: String = “me “):String?= “ hello “

2.函数嵌套
不推荐使用,降低代码可读性
在某些条件下触发递归的函数,或者不希望被外部函数访问到的函数,
如,对外只是function,say不被外部函数访问
fun function() {
val str = “hello”
fun say(count: Int) {
println(“$str,$count”)
if (count > 0) {
say(count - 1)
}
}
say(5)
}


扩展函数
静态的给一个类添加一个方法或者一个变量,不具备运行时多态
扩展成员方法,成员变量
fun KtObject.hello: String = “ hello “

in java
KtObjectKt.hello(object) 有待验证


闭包
val echo = {
name: String ->
println(name)
}
echo(“hello”)

原理:就是匿名内部类
lambda参数上限是22个,可以手动定义在延长这个上限


高阶函数,
类里的方法可以当作参数赋值,
inline建议只用于高阶函数,不然会加重编译器的负担,等于把语句嵌进去

inline fun onlyif(isDebug: Boolean, block: ()->Unit) {
if (isDebug) {
block()
}
}
fun main(args: Array<String>) {

val runnable = Runnable {  
    println("runnable")  
}  

val function: () -\> Unit  
function = runnable::run  

onlyif(true, function)  

}


类与对象
class A:B {}
open class

open class(var int:Int): B(){
val v
init{
v = 5
}
constructor(int :Int):super(int)
constructor(int:int, str:String):this(int)

}

伴生对象,,,单例
kotlin 是没有static关键字的
private
protected
publick
internal 模块内可以访问,,,即module
伴生对象:
class A {
companion object {
fun isEmpty(str:String?): Boolean {}
}
}

kotlin A.isEmpty(xxx)
java A.Companion.isEmpty(xxx) 生成一个static对象Compantion

伴生对象用来生成单例

class Single private constructor() {
companion object {
fun get(): Single() {
return Holder.instance
}
}
private object Holder {
val instance = Single()
}
}

java动态代理就是指一般静态代理基础上,为了解决静态代理需要写很多代理方法带来的重复工作,从而利用放射在运行时自动去寻找对应的代理方法。
kotlin的动态代理 使用by关键字

如果是以前java,一般做法是采用静态代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
interface Animal {
fun bark()
fun jump()
}

class Dog: Animal {
override fun jump() {
println("jump")
}

override fun bark() {
println("bark")
}
}

//静态代理类
class Zoo(animal: Animal): Animal{
var mAnimal: Animal? = null
init {
mAnimal = animal
}
override fun jump() {
mAnimal?.jump()
}
override fun bark() {
mAnimal?.bark()
}
}

class TestAnimal {
companion object {
@JvmStatic
fun main(args: Array<String>) {
Zoo(Dog()).bark()
Zoo(Dog()).jump()
}

}
}

kotlin使用by关键字来做伪动态代理,而不用反射,最终编译成静态代理

1
class Zoo(animal: Animal): Animal by animal

kotlin 枚举类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
enum class Command {
A, B, C, D
}

fun exec(command: Command) = when(command) {
A -> {
println("A!")
}
B -> {
println("B!")
}
C -> {
println("C!")
}
D -> {
println("D!")
}
}

kotlin 密封类《超级枚举类》 暂时不知道exec有什么好处

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
sealed class SuperCommand {
object A : SuperCommand()
object B : SuperCommand()
object C : SuperCommand()
object D : SuperCommand()
class E(var id: Int) : SuperCommand()
}

fun exec(superCommand: SuperCommand) = when(superCommand) {
SuperCommand.A -> {
println("AA")
}
SuperCommand.B -> {
println("BB")

}
SuperCommand.C -> {
println("CC")

}
SuperCommand.D -> {
println("DD")

}
is SuperCommand.E -> {
println("EE")
}
}

oop

1
2
3
1interface+实现类,消除ifelse类的代码,把动作赋给对象
2、代理类代理interface,以便对interface的统一修改,也可以视为不要污染了原来的类
3、每个类都有自己的行为,如果不是这个类发出的,抽出去独立的类实现