请写出下面这段代码的输出结果?
class Shape{
Shape(int i){
System.out.println("This is Shape" + i);
}
}
public class Circle extends Shape{
static Shape s1 = new Shape(1);
Shape s2 = new Shape(3);
Circle(int i){
super(i);
System.out.println("This is Circle" + i);
} public static void main(String args[]){
Circle c1 = new Circle(2);
}
}
class Shape{
Shape(int i){
System.out.println("This is Shape" + i);
}
}
public class Circle extends Shape{
static Shape s1 = new Shape(1);
Shape s2 = new Shape(3);
Circle(int i){
super(i);
System.out.println("This is Circle" + i);
} public static void main(String args[]){
Circle c1 = new Circle(2);
}
}
解决方案 »
- 高分求解多线程问题!
- 多线程问题
- Java Import 问题
- 求一个正则阿
- 高份求解2题
- addShutdownHook()在Linux下无效!?
- 郁闷得要自杀呀,这到底是怎么一回事啊。请好心人救救我,给我口气吧。
- 在哪儿有Effective Java这本书的电子版下?中英文都可以
- Jbuilder 5 做安装程序
- 在JB5里做了一个实体BEAN,SQLSERVER的驱动也已经填加到JB5的LIBRARIES里,做的过程中一切都正常,连接数据库都正常,但我用客户端测试的时候却出现以下问题,昨天发了一个求救,被管理员删了,希望今天别删了
- 序列化与反序列化问题,为什么两个对象不相等
- 求个Java采集类
This is Shape2
This is Shape3
This is Circle2分析过程:
1、JVM在运行class时,首先会扫描一次全部的程序,静态块优先级最高,因为它们会存储在JVM的公共内存区域。
2、接着会调用构造方法,构造方法调用的顺序是,JVM会先扫描类的继承关系,然后从最顶层的构造方法向下执行。
3、执行到指定类内部时,会先处理类中定义的实例变量,然后再执行构造方法内部的代码。
所以得到上面的结果。
第一步,static Shape s1 = new Shape(1);这里调用基类的构造函数,输出This is Shape1;
第二步,依据继承关系调用构造函数。由于main函数里是 Circle c1 = new Circle(2);先调用Shape类的构造函数,输出This is Shape2;然后调用Circle类的构造函数,其构造函数是
Circle(int i){
super(i);
System.out.println("This is Circle" + i);
}
我就晕了,第一句是调用Shape类的构造函数吧?那是不是输出This is Shape 2;This is Circle 2 ?
再接着按实例, Shape s2 = new Shape(3);那就是输出This is Shape 3;
最后再执行构造方法内部的代码,又是 super(i);
System.out.println("This is Circle" + i);
不敢往下写了~~~
//Shape s2 = new Shape(3);
Shape s2 = null;
Circle(int i) {
super(i);
s2 = new Shape(3);
System.out.println("This is Circle" + i);
} public static void main(String args[]) {
Circle c1 = new Circle(2);
}}
1、静态先于非静态,静态包括静态实例变量,静态代码块;
2、父类先于子类;
3、同级的以代码书写顺序执行;
4、同类中实例变量先与构造方法;所以最后顺序就是:
先父类的静态-子类的静态-父类实例变量-父类构造方法-子类实例变量-子类构造方法
为什么JVM会用这个顺序来初始化对象,其实想都想得明白:如果静态的东西不先初始化,我们的静态方法就没法调用了;如果实例变量不先初始化,我们的构造方法里如果用到了那个变量就会出错;如果父类的不先初始化,我们子类的构造方法用到了父类的东西也会出错。
所以结果就是
shape 1(子类静态)
shape 2(父类构造方法)
shape 3(子类实例变量)
circle 2(子类构造方法)
你可以理解为super是执行基类的同名方法
你也可以重写自己的方法不调用基类的,把super去掉就好
Circle(int i){
super(i);
System.out.println("This is Circle" + i); ///////////////222222222
}
1要比2先执行,同类中实例变量要比构造方法先执行;如果实例变量没有执行,写程序的时候很多构造函数里都要调用自己类的实例变量。