八、对象的初始化过程
Person p = new Person("zhangsan",20);这句话都进行了哪些操作?
首先栈内存中生成一个引用变量p,其次
1、因为new用到了Person.class,所以会先找到Person.class文件并加载到内存中。
2、执行该类中的静态代码块,(如果有的话),给Person.class类进行初始化。
3、在内存中开辟空间,分配内存地址。
4、在堆内存中建立对象的特有属性,并进行默认初始化。
5、对属性进行显示初始化。
6、对对象进行构造代码块初始化。
7、对对象进行对应的构造函数初始化。
8、将内存地址赋给内存中的p变量。
九、单例设计模式
目的:保证类的对象在内存中唯一。实现方式有三种
1、饿汉式
private static Person p = new Person();
private Person(){}
public static Person getInstance(){
return p;
}
2、懒汉式,延迟加载(有线程安全问题)
private static Person p = null;
private Person(){}
public static syschronized Person getInstance(){
if(s == null){
// -->A
// -->B
s = new Person();
}
return p;
}
3、懒汉式(解决线程安全问题)
private static Person p = null;
private Person(){}
public static Person getInstance(){
if(s == null){
synchronized(Person.class){ //注意,静态方法中的同步锁为调用类的字节码
if(s == null){
s = new Person();
}
}
}
return p;
}
十、重载和重写区别
重载(Overload):在同一范围中声明几个功能类似的同名函数,但是同名函数的形式参数(参数个数、类型或者顺序)必须不同。
1、同名
2、形参(个数、类型、顺序)不同
覆写(重写 Override):
1、在继承中
2、方法名、返回值、形参(个数、类型、顺序)都必须相同
3、权限,子类重写的方法权限不能低于基类
4、异常,子类抛出的异常不能比基类大。父类有多个异常,子类只能抛出父类的异常子集。
父类方法没有抛出异常,覆盖时子类方法也不能抛出异常。
如果子类覆盖的方法中有异常抛出,那么只能try{}catch(){}
5、泛型,父类没有放行,子类可以有。父类如果指定泛型,子类必须与父类一致(或者不指定)。
十一、聚集关系
聚合:球员与球队之间的关系(单独也可以使用)
组合:(事物连接更紧密)如人体器官与人的关系(单独不可以使用)
十二、实践得到创建子类对象时的执行顺序:
(1)加载父类,执行父类静态成员,静态代码块
(2)加载子类,执行子类静态成员,静态代码块
(3)父类成员初始化,执行父类构造代码块,父类构造函数
(4)子类开辟空间,成员初始化,执行子类构造代码块,子类构造函数
十三、内部类访问规则
1、内部类可以直接访问外部类中的成员,包括私有。
这是因为内部类中持有一个外部类的引用,格式为:外部类名.this(如p.this):Person.this.成员变量。
2、外部类要访问内部类,必须建立内部类的对象
3、其他类访问某个内部类(这个内部类需要在外部类的成员位置上,且没有私有化)需要这样创建对象:
Outer.Inner in = new Outer().new Inner();
4、内部类可以私有化。