1:程序题----------类初始化和实例初始化
父类:
public class Father {
private int i = test();
private static int j = method();
static{
System.out.println("(1)");
}
Father() {
System.out.println("(2)");
}
{
System.out.println("(3)");
}
public int test() {
System.out.println("(4)");
return 1;
}
public static int method() {
System.out.println("(5)");
return 1;
}
}
子类:
public class Son extends Father{
private int i = test();
private static int j = method();
static{
System.out.println("(6)");
}
public Son() {
super();//写与不写,在子类构造器一定回调用父类的构造器
System.out.println("(7)");
}
{
System.out.println("(8)");
}
public int test() {
System.out.println("(9)");
return 1;
}
public static int method() {
System.out.println("(10)");
return 1;
}
public static void main(String[] args) {
Son s1= new Son();
System.out.println();
Son s2= new Son();
}
}
思考一下,运行这段代码会输出什么?
运行结果为:
考点如下:
1:类初始化过程
2:实例初始化过程
3:方法的重写
1:类初始化过程
例如:我在将Son中的main方法运行,但不实例化对象,来看下类初始化过程,执行结果如下:
这里的main在Son中,要初始化子类,需要先初始化父类,再初始化子类:
- 子类的初始化
- (1)子类的静态变量j = method();
- (2)子类的静态代码块
- 先初始化父类(5)(1)
- 再初始化子类(10)(6)
2:实例初始化过程
父类的实例化方法:
- (1)super()-----最前
- (2) 非静态变量;
- (3) 非静态代码块;按照顺序执行
- (4)类的无参构造器—最后
子类的实例化方法: - (1)super()-----最前(9)(3)(2)
- (2) 非静态变量;(9)
- (3)非静态代码块;按照顺序执行(8)
- (4)子类的无参构造器—最后(7)
- 因为创建了两个son对象,因此实例化方法执行两次
- (9)(3)(2)(9)(8)(7)
这里有一个疑问就是,为什么父类实例化非静态变量的时候,调用的是子类的test方法呢?第三个知识点
3:方法的重写
非静态方法前面是有一个默认的对象this - this在构造器(或init方法中)他表示的是正在创建的对象,因为这里是在创建子类对象
- 所以在类的实例化的时候i = test()执行的是子类重写的方法
题目资源
2 程序题----------方法的参数传递机制
题目考点;
方法的参数传递机制
String ,包装类等对象的不变性
方法的参数传递机制
1:若实参是基本数据类型----传递数据值
2:若实参是引用数据类型----传递地址值,特殊类型: String ,包装类等对象的不变性
分析过程:
基本数据类型存储在栈上
new的对象,在堆上
引用型字符串在常量池
这里的包装类Integer,值为200,不在缓存对象范围-128~127,所以在堆中存放
当调用函数change(),会在栈中再次开辟一个方法区,按照方法的参数传递机制,将参数传递,并进行方法区中的操作,该方法执行完毕后,栈中上面的方法区就会被回收。
从上图可以看出,经过change方法操作后,
对于int i;string str,num,对应的值不变。对于数组,由于操作直接操作了堆中的数据,因此arr发现了变化,Mydata对象,a的值,也在堆中被修改。