面向对象的三个特征
封装,继承,多态
封装:把对象特征数据化封装起来
继承:继承父类,复用数据和方法
多态:重载和重写的时候,对相同方法(方法名相同)做出不同的操作
成员变量,
method(方法区)又叫静态区,存放所有的①类(class),②静态变量(static变量),③静态方法,④常量和⑤成员方法。被所有的线程共享。方法区中存放的都是在整个程序中永远唯一的元素。这也是方法区被所有的线程共享的原因。
public class Test1 {
public static void main(String[] args) {
String s11 = new String("aa");
String s2 = s11.intern();
String s3 = s11;
String s1 = "aa";
System.out.println(s1 == s2);//返回true
System.out.println(s1 == s3);//返回false
}
}
返回具体常量池里具有相同值的字符串对象.
intern方法首先会查找常量池是否有相同值的字符串,如果有就返回,没有就在常量池上创建对应字符串并返回.注意:如果本身这个字符串就在常量池里,就返回对象本身,否则返回在常量池上新创建的对象,
返回false。在编译过程中,编译器会将s2直接优化为”ab”,会将其放置在常量池当中,s5则是被创建在堆区,相当于s5=new String(“ab”);
public class Test2 {
public static void main(String[] args) {
String s1 = "ab";
String s2 = "a" + "b";
String s3 = "a";
String s4 = "b";
String s5 = s3 + s4;//
// 请问s5 == s2\
System.out.println(s5 == s1);//false
System.out.println(s2 == s1);//true
System.out.println(s5 == s2);//false
}
}
String s1=”ab” ;位于常量池
String s2=”a”+”b”;编译的时候转化成 s2=”ab”,类似s1,在常量池
String s3=”a”, String s4=”b”;在常量池,类似s1
String s5=s3+s4;位于堆,编译器不知道这个s3,s4是否在常量池上,字符串实例化在堆上.
==是一个比较运算符,基本数据类型比较的是值,引用数据类型比较的是地址值。
(比较地址值即是指是否为同一个对象的引用)。
equals()是一个方法,只能比较引用数据类型。重写前比较的是地址值,重写后比一般是比较对象的属性。
如果equals,那么hashcode也要设计为相等,否则会找出list的contains错误。所以在重写eqauls方法的时候一定要重写hashcode方法
浅拷贝:被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象。
深拷贝:被复制对象的所有变量都含有与原来的对象相同的值,而那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深拷贝把要复制的对象所引用的对象都复制了一遍。
取决于java的编码,linux里面java默认编码是utf-8,所占字节有下面几种情况:
ClassCastException(类转换异常)
IndexOutOfBoundsException(数组越界)
NullPointerException(空指针)
SecurityException
数学上除以0的异常
序列化的目的:
实现的两种方式Serializable,Parcelable
Parcelable与Serializable的性能比较
Parcelable性能明显高于Serializable
Serializable是通过ObjectOutputStram把序列化数据保存在磁盘,Parcelable一般跨进程传递保存在内存的数据,Parcelable如果也要保存到本地,需要利用Parcel方法marshall 和 unmarshall,把对数转换为byte数组。
Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable 。
如何理解:在外界发生改变后,Parcelable不能使用在要将数据存储在磁盘上的情况不能很好的保证数据的持续性?
应该是磁盘序列化后在改变Parcelable实现类之后(外界发生改变后),Parcelable反序列会出现问题(不能保证数据的持续性).
serialVersionUID适用于Java的序列化机制。简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常,即是InvalidCastException。
具体的序列化过程是这样的:序列化操作的时候系统会把当前类的serialVersionUID写入到序列化文件中,当反序列化时系统会去检测文件中的serialVersionUID,判断它是否与当前类的serialVersionUID一致,如果一致就说明序列化类的版本与当前类版本是一样的,可以反序列化成功,否则失败。
几种情况A端序列化,B端反序列化,参考https://www.cnblogs.com/duanxz/p/3511695.html:
情况一:A端和B端都需要存在一个相同的类。如果两处的serialVersionUID不一致,异常java.io.InvalidClassException
情况二:假设两处serialVersionUID一致,如果A端增加一个字段,然后序列化,而B端不变,然后反序列化;执行序列化,反序列化正常,但是A端增加的字段丢失(被B端忽略)
情况三:serialVersionUID一致,如果B端减少一个字段,A端不变;序列化,反序列化正常,B端字段少于A端,A端多的字段值丢失(被B端忽略)。
情况四:假设两处serialVersionUID一致,如果B端增加一个字段,A端不变;说明序列化,反序列化正常,B端新增加的int字段被赋予了默认值
情况三四五就是最终反序列化总是得到a和b两最少的数据
静态变量序列化:
序列化保存的是对象的状态(成员变量的值),静态变量属于类的状态,因此 序列化并不保存静态变量
父类的序列化与 Transient 关键字
问题:一个子类实现了 Serializable 接口,它的父类都没有实现 Serializable 接口,序列化该子类对象,然后反序列化后输出父类定义的某变量的数值,该变量数值与序列化时的数值不同.
解决:要想将父类对象也序列化,就需要让父类也实现Serializable 接口。如果父类不实现的话的,就 需要有默认的无参的构造函数。在父类没有实现 Serializable 接口时,虚拟机是不会序列化父对象的,而一个 Java 对象的构造必须先有父对象,才有子对象,反序列化也不例外。所以反序列化时,为了构造父对象,只能调用父类的无参构造函数作为默认的父对象。因此当我们取父对象的变量值时,它的值是调用父类无参构造函数后的值。如果你考虑到这种序列化的情况,在父类无参构造函数中对变量进行初始化,否则的话,父类变量值都是默认声明的值,如 int 型的默认是 0,string 型的默认是 null。
Transient 关键字的作用是控制变量的序列化,在变量声明前加上该关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null。
特性使用案例
我们熟悉使用 Transient 关键字可以使得字段不被序列化,那么还有别的方法吗?根据父类对象序列化的规则,我们可以将不需要被序列化的字段抽取出来放到父类中,子类实现 Serializable 接口,父类不实现,根据父类序列化规则,父类的字段数据将不被序列化
measure过程、layout过程、draw过程
measure:测量VIew的高度,宽度
layout:确定view的位置
draw:绘制view
startservice:onCreate->onstarCommand->onDestory
onbindeService:onCreate->onbind->onUnbide->onDestory
这个问题真的很不好回答。所以先比较恰当的比喻来形容下它们的关系,Activity像一个工匠(控制单元),Window像窗户(承载模型),View像窗花(显示视图)LayoutInflater像剪刀,Xml配置像窗花图纸。
1:Activity构造的时候会初始化一个Window,准确的说是PhoneWindow。
2:这个PhoneWindow有一个“ViewRoot”,这个“ViewRoot”是一个View或者说ViewGroup,是最初始的根视图。
3:“ViewRoot”通过addView方法来一个个的添加View。比如TextView,Button等
4:这些View的事件监听,是由WindowManagerService来接受消息,并且回调Activity函数。比如onClickListener,onKeyDown等。
直接在onCreate就finish掉activity、
graph LR
开始 --> onCreate,onStart,onRestart,onResume
onCreate,onStart,onRestart,onResume --> 运行
运行 --> onpause
onpause --> 暂停
暂停 --> onstop
onstop --> 停止
停止 --> onDestory
onDestory --> 销毁