JMVP的kotlin版本
此项目是JMVP的Kotlin版本,目的在于学习kotlin语法的应用
Android Kotlin开发
共6Star
详细介绍
关于
此项目是JMVP的Kotlin版本,目的在于学习kotlin语法的应用。
JMVP地址在此
README
完成了JMVP基本的MVP架构的kotlin实现。
重点记录
修饰符
重要修饰符含义需要注意:open, companion object{}, @Synchronized
-
open
:在非abstract标记下使用,仅用于方法的标识(对对象无效),标识该方法可被重写。kotlin默认情况下所有fun都是可被调用的的,类似于public
,但是无法被重写,对比java中方法的final
标记。如果要让一个方法既能被调用又能被重写,则加上open,如果不想某个方法被外部访问,那么加上private标记 -
object
:用于声明对象,在单例模式、匿名对象中皆有运用 -
companion object{}
:伴生对象,对比java中的static,可以包含对象和方法 -
@Synchronized
:同步修饰符,和java的synchronized
一样 -
in
:泛型中的运用,作用是表示该泛型是对内有效作为一个消费品,比如声明一个class A<in T>
,那么内部可以拥有方法fun setA(a: T) {}
,这里外界决定到来的对象类型只能在内部消费使用 -
out
:泛型中的运用,作用是表示该泛型是对外的返回结果,是个生产品,比如针对class A<out T>
,可以拥有fun getA(): T {}
。具体一点,比如我们拥有一个泛型接口A如下:public interface A<T extends Activity> { T getA(); }
在java中是这么用的。
public void a(A<BaseActivity> a){ A<? extends Activity> a1 = a; }
而在kotlin中是这样定义和使用的
interface A<out T: Activity> { fun getA(): T }
使用
fun a(a: A<BaseActivity>) { var a1: A<Activity> = a }
事实上,在Java中,如果我们在声明一个A的时候不使用
? extends Activity
的话,那么我们只能使用具体的类型,否则编译阶段就无法通过,而使用具体类型的话泛型就失去了意义
而在Kotlin中,如果不加上out,那么也是一样的结果,要么明确声明类型,要么就编译报错
javaClass 和 class.java
当在使用反射机制的时候,总是会去获取这个对象的class类型,以及其field或者method,后两者使用都比较明确,比如我们有一个var cls: Class<*>;要获取cls的field,直接调用cls.fields就行了,这点在kotlin中是很明确的。
但是当我们要获取一个对象的类的时候,会发现有两个方法,一个是cls::javaClass,另外一个是cls::class.java。二者有着一些相同的地方,比如.name、.annotations这些调用结果是一样的,但是也有一些区别。
- javaClass获取到的对象在断点调式中看到的是一个property javaClass。也就是说这是一个javaClass属性,其在内存中的名字也不一样,显示为一个对象内部属性,例如:ViewInjector$Companion$injectView$ojc$1@4636
- class.java获取到的则显示为class java.lang.Object,其在内存中的名字则是这样类型的:Class@564
所以,我们可以得出一些结论,kotlin中javaClass是作为一个具体实例化对象(这个对象是Kotlin中的Any的子类实例化,在Java中则是java.lang.Object的子类实例化,Any和Object在两种语言编译环境下转成字节码后应该是一样的)的一个属性存在,而class.java就像Java中调用getClass是一样的。是一个固定类型,不管我一个对象是在Activity中实例化,还是在ViewHolder中实例化,class.java是一样的,但是javaClass则明显不同。
所以,在Kotlin语法中使用Java的反射机制这样的特性的时候,需要注意二者的区别,至少不会在出现bug的时候手足无措。
superClass和::class.java.superclass也是一样的原理
其他
kotlin中很多注解使用都是加上一个@然后作为修饰符在使用
当对象为泛型而其夫类也要声明泛型的时候,对其的引用使用需要注意:
abstract class BaseMVPActivity<MajorPresenter: BaseKTPresenter<*, *>, MajorModel: BaseKTModel>: BaseActivity() {}
//BaseKTPresenter本身也需要泛型定义,而这里未知,所以传递*(正确与否尚未验证,目前是编译没错)
对比java中的使用
public abstract class BaseMVPActivity<MajorPresenter extends BaseJPresenter, MajorModel extends BaseJModel> extends BaseActivity {}
-
21 Star
-
545 Star
-
229 Star
-
0 Star
-
1828 Star
-
1124 Star