whatshappen
whatshappen
保活不了,死球了
synchronized保证了程序执行的可见性和原子性; volatile只保证了程序的可见性,禁止指令的重排序;
深拷贝是址拷贝,浅拷贝是值拷贝
equals 比较的是值和地址,如果没有重写equals方法,其作用与==相同; 在String中重写了equals方法,比较的是值是否相等; hashCode用于散列数据结构中的hash值计算; equals两个对象相等,那hashcode一定相等,hashcode相等,不一定是同一个对象;
> 没有弊端啊? 扩展不能真正的修改他们所扩展的类。通过定义⼀个扩展,你并没有在⼀个类中插⼊新成员,仅仅是可以通过该类型的变量⽤点表达式去调⽤这个新函数。 open class C class D: C() fun C.foo() = "c" //类C的扩展函数 fun D.foo() = "d" //类D的扩展函数 fun printFoo(c: C) { //扩展函数根据函数调用所在的表达式类型决定的,c是C类型的,所以传入D类的对象,也会调用的是C类的扩展函数 println(c.foo()) } fun main(args: Array) {...
> 666,我都是叫SDK提供方帮我删 what?
1.handler机制中多个handler共有一个looper不会错乱是因为在handler 发送消息的时候,会将当前的handler对象绑定到message的target属性上,然后在Looper取到消息后通过msg.target拿到之前的handler对象,然后调用handler的handleMessage方法。 2.消息延迟的原理:handler发送延迟消息,会将当前的延迟时间绑定到msg的when属性上,然后在循环MessageQUeue获取msg时判断如果当前有延迟就进行阻塞,通过计时器计算时间,时间通过系统启动计算时间,然后等待阻塞时间结束之后将其唤醒,在阻塞过程中会将之后的消息放在消息队列的头部去处理。 3.同一个线程中可以有多个Handler,只有一个Looper,而MessageQueue在looper中初始化的,所以也只有一个MessageQueue。因此对应关系是:Handler:Looper = 多对一,Looper:MeesageQueue = 一对一,Handler:MessageQueue = 多对一。 4.Handler的内存泄漏是由于Handler持有外部类的引用,使其无法释放。 解决办法:(1)定义成静态内部类,使其不持有外部类的引用;(2)可以使用弱引用; 还需要在外部类销毁的时候,移除所有的消息。 5.可以说整个应用的生命周期都是在looper.loop()控制之下的(在应用启动的入口main函数中初始化ActivityThread,Handler,Looper,然后通过handler和looper去控制初始化应用)。而looper.loop采用的是Linux的管道机制,在没有消息的时候会进入阻塞状态,释放CPU执行权,等待被唤醒。真正会卡死主线程的操作是在回调方法onCreate/onStart/onResume等操作时间过长,会导致掉帧,甚至发生ANR,looper.loop本身不会导致应用卡死。
lateinit var只能用来修饰类属性,不能用来修饰局部变量,并且只能用来修饰对象,不能用来修饰基本类型(因为基本类型的属性在类加载后的准备阶段都会被初始化为默认值)。 by lazy要求属性声明为val,即不可变变量,在java中相当于被final修饰。这意味着该变量一旦初始化后就不允许再被修改值了(基本类型是值不能被修改,对象类型是引用不能被修改)。{}内的操作就是返回唯一一次初始化的结果。
**方式一**:给字段加上 transient 修饰符 **方式二**:排除Modifier指定类型的字段。这个方法需要用GsonBuilder定制一个GSON实例。 **方式三**:使用@Expose注解。没有被 @Expose 标注的字段会被排除