{
Y b=new Y();
X()
{
System.out.print("X");
}
}
class Y
{
Y()
{
System.out.print("Y");
}
}
public class Z extends X
{
Y y=new Y();
Z()
{
System.out.print("Z");
}
public static void main(String[] args)
{
new Z();
}
}
两个问题请教大家:1.运行结果;2.分析结果.
8 个解决方案
#1
YXYZ 就是初始化顺序的问题
super() 成员变量初始化 构造器体
super() 成员变量初始化 构造器体
#2
YXYZ
这个题考得是子类初始化顺序以及属性和构造初始化顺序。
在new一个Z的时候,由于它有父类,因此先初始化父类X(这个很好理解,既然子类继承父类,那当然是父类给有东西才能继承,因此为了防止子类在初始化时用到父类的东西,自然给先把父类初始化出来。)于是到X的内部,它有一个属性还有一个构造,那么先初始化哪个呢?通常在构造里我们都会对类的属性进行一些操作(这点你可以看看现成代码,很多都这样),如果构造执行在先那么在操作属性时,属性还没初始化怎么行。所以要先初始化属性Y。于是又转到Y里,Y比较简单没属性,构造里输出“Y”即可,然后在执行X的构造输出“X”,这时候父类X初始化完了,再接着初始化Z,还是先初始化属性,那么输出“Y”,然后再输出构造里的“Z”。
实际上这道题是简化很多的。因为它没有考到静态属性(类属性)以及程序块及静态程序块。
我把这个题改一下,你运行一下对照结果,应该会有些收获的。
public class Z extends X{
static{ //静态代码块
System.out.println("我是子类的静态代码块,除了父类静态代码块和静态属性(类变量)我是最先执行的");
}
static C c= new C(); //静态属性
Y2 y=new Y2();
{ System.out.println("我是子类初始化块,我的优先级和非静态属性一样,我们之间的顺序以代码顺序为准"); } //初始化块
Z(){System.out.println("我是子类构造函数");}
public static void main(String[] args){
new Z();
}
}
class X{
static{System.out.println("我是父类的静态代码块,我是最先执行的"); } //静态代码块
static C2 c= new C2(); //静态属性
{ System.out.println("我是父类初始化块,我的优先级和非静态属性一样,我们之间的顺序以代码顺序为准"); } //初始化块
Y b=new Y(); //非静态属性
X(){System.out.println("我是父类构造函数");}
}
class Y{
Y(){System.out.println("我是父类非静态属性,和具体的类实例相关,我可能在初始化块前执行也可能在其后");}
}
class Y2{
Y2(){System.out.println("我是子类非静态属性,和具体的类实例相关,我可能在初始化块前执行也可能在其后");}
}
class C{
C(){System.out.println("我是子类的一个静态属性(类变量),我和之前的初始化过程都是针对类的,与实例无关");}
}
class C2{
C2(){System.out.println("我是父类一个静态属性(类变量),我比子类的静态代码块执行的还早");}
}
这个题考得是子类初始化顺序以及属性和构造初始化顺序。
在new一个Z的时候,由于它有父类,因此先初始化父类X(这个很好理解,既然子类继承父类,那当然是父类给有东西才能继承,因此为了防止子类在初始化时用到父类的东西,自然给先把父类初始化出来。)于是到X的内部,它有一个属性还有一个构造,那么先初始化哪个呢?通常在构造里我们都会对类的属性进行一些操作(这点你可以看看现成代码,很多都这样),如果构造执行在先那么在操作属性时,属性还没初始化怎么行。所以要先初始化属性Y。于是又转到Y里,Y比较简单没属性,构造里输出“Y”即可,然后在执行X的构造输出“X”,这时候父类X初始化完了,再接着初始化Z,还是先初始化属性,那么输出“Y”,然后再输出构造里的“Z”。
实际上这道题是简化很多的。因为它没有考到静态属性(类属性)以及程序块及静态程序块。
我把这个题改一下,你运行一下对照结果,应该会有些收获的。
public class Z extends X{
static{ //静态代码块
System.out.println("我是子类的静态代码块,除了父类静态代码块和静态属性(类变量)我是最先执行的");
}
static C c= new C(); //静态属性
Y2 y=new Y2();
{ System.out.println("我是子类初始化块,我的优先级和非静态属性一样,我们之间的顺序以代码顺序为准"); } //初始化块
Z(){System.out.println("我是子类构造函数");}
public static void main(String[] args){
new Z();
}
}
class X{
static{System.out.println("我是父类的静态代码块,我是最先执行的"); } //静态代码块
static C2 c= new C2(); //静态属性
{ System.out.println("我是父类初始化块,我的优先级和非静态属性一样,我们之间的顺序以代码顺序为准"); } //初始化块
Y b=new Y(); //非静态属性
X(){System.out.println("我是父类构造函数");}
}
class Y{
Y(){System.out.println("我是父类非静态属性,和具体的类实例相关,我可能在初始化块前执行也可能在其后");}
}
class Y2{
Y2(){System.out.println("我是子类非静态属性,和具体的类实例相关,我可能在初始化块前执行也可能在其后");}
}
class C{
C(){System.out.println("我是子类的一个静态属性(类变量),我和之前的初始化过程都是针对类的,与实例无关");}
}
class C2{
C2(){System.out.println("我是父类一个静态属性(类变量),我比子类的静态代码块执行的还早");}
}
#3
YXYZ
“实例化”一个类时先去把父类实例话,然后把成员变量初始化,然后再构造函数。
所以new Z()时先去实例化Z的父类X。在实例化X时,X没有父类,所以初始化成员Y,这时打印第一个Y,然后调用X的构造函数,这时打印X,
Z的父类实例完后就实例化Z的成员变量,只有一个成员变量Y,这时打印第二个Y,然后最后调用Z的构造函数,这时打印Z
“实例化”一个类时先去把父类实例话,然后把成员变量初始化,然后再构造函数。
所以new Z()时先去实例化Z的父类X。在实例化X时,X没有父类,所以初始化成员Y,这时打印第一个Y,然后调用X的构造函数,这时打印X,
Z的父类实例完后就实例化Z的成员变量,只有一个成员变量Y,这时打印第二个Y,然后最后调用Z的构造函数,这时打印Z
#4
谢谢各位,尤其是二楼的细心~~
#5
实例化一个类时,首先去实例化父类,再去实例化子类,类中的成员变量和构造函数,首先去初始化其成员变量,然后再执行构造函数。你可以做一下测试:
class X {
String str = this.getStr();
Y b = new Y();
X() {
System.out.print("X ");
}
String getStr(){
System.out.println("我要初始化成员变量");
return "0000";
}
}
class Y {
Y() {
System.out.print("Y ");
}
}
public class Z extends X {
Y y = new Y();
Z() {
System.out.print("Z ");
}
public static void main(String[] args) {
System.out.println("---------");
new Z();
}
}
class X {
String str = this.getStr();
Y b = new Y();
X() {
System.out.print("X ");
}
String getStr(){
System.out.println("我要初始化成员变量");
return "0000";
}
}
class Y {
Y() {
System.out.print("Y ");
}
}
public class Z extends X {
Y y = new Y();
Z() {
System.out.print("Z ");
}
public static void main(String[] args) {
System.out.println("---------");
new Z();
}
}
#6
不错,学习
#7
很好!
#8
恩,不错 ,仔细点分析还是能做对的。我为自己感到骄傲
#1
YXYZ 就是初始化顺序的问题
super() 成员变量初始化 构造器体
super() 成员变量初始化 构造器体
#2
YXYZ
这个题考得是子类初始化顺序以及属性和构造初始化顺序。
在new一个Z的时候,由于它有父类,因此先初始化父类X(这个很好理解,既然子类继承父类,那当然是父类给有东西才能继承,因此为了防止子类在初始化时用到父类的东西,自然给先把父类初始化出来。)于是到X的内部,它有一个属性还有一个构造,那么先初始化哪个呢?通常在构造里我们都会对类的属性进行一些操作(这点你可以看看现成代码,很多都这样),如果构造执行在先那么在操作属性时,属性还没初始化怎么行。所以要先初始化属性Y。于是又转到Y里,Y比较简单没属性,构造里输出“Y”即可,然后在执行X的构造输出“X”,这时候父类X初始化完了,再接着初始化Z,还是先初始化属性,那么输出“Y”,然后再输出构造里的“Z”。
实际上这道题是简化很多的。因为它没有考到静态属性(类属性)以及程序块及静态程序块。
我把这个题改一下,你运行一下对照结果,应该会有些收获的。
public class Z extends X{
static{ //静态代码块
System.out.println("我是子类的静态代码块,除了父类静态代码块和静态属性(类变量)我是最先执行的");
}
static C c= new C(); //静态属性
Y2 y=new Y2();
{ System.out.println("我是子类初始化块,我的优先级和非静态属性一样,我们之间的顺序以代码顺序为准"); } //初始化块
Z(){System.out.println("我是子类构造函数");}
public static void main(String[] args){
new Z();
}
}
class X{
static{System.out.println("我是父类的静态代码块,我是最先执行的"); } //静态代码块
static C2 c= new C2(); //静态属性
{ System.out.println("我是父类初始化块,我的优先级和非静态属性一样,我们之间的顺序以代码顺序为准"); } //初始化块
Y b=new Y(); //非静态属性
X(){System.out.println("我是父类构造函数");}
}
class Y{
Y(){System.out.println("我是父类非静态属性,和具体的类实例相关,我可能在初始化块前执行也可能在其后");}
}
class Y2{
Y2(){System.out.println("我是子类非静态属性,和具体的类实例相关,我可能在初始化块前执行也可能在其后");}
}
class C{
C(){System.out.println("我是子类的一个静态属性(类变量),我和之前的初始化过程都是针对类的,与实例无关");}
}
class C2{
C2(){System.out.println("我是父类一个静态属性(类变量),我比子类的静态代码块执行的还早");}
}
这个题考得是子类初始化顺序以及属性和构造初始化顺序。
在new一个Z的时候,由于它有父类,因此先初始化父类X(这个很好理解,既然子类继承父类,那当然是父类给有东西才能继承,因此为了防止子类在初始化时用到父类的东西,自然给先把父类初始化出来。)于是到X的内部,它有一个属性还有一个构造,那么先初始化哪个呢?通常在构造里我们都会对类的属性进行一些操作(这点你可以看看现成代码,很多都这样),如果构造执行在先那么在操作属性时,属性还没初始化怎么行。所以要先初始化属性Y。于是又转到Y里,Y比较简单没属性,构造里输出“Y”即可,然后在执行X的构造输出“X”,这时候父类X初始化完了,再接着初始化Z,还是先初始化属性,那么输出“Y”,然后再输出构造里的“Z”。
实际上这道题是简化很多的。因为它没有考到静态属性(类属性)以及程序块及静态程序块。
我把这个题改一下,你运行一下对照结果,应该会有些收获的。
public class Z extends X{
static{ //静态代码块
System.out.println("我是子类的静态代码块,除了父类静态代码块和静态属性(类变量)我是最先执行的");
}
static C c= new C(); //静态属性
Y2 y=new Y2();
{ System.out.println("我是子类初始化块,我的优先级和非静态属性一样,我们之间的顺序以代码顺序为准"); } //初始化块
Z(){System.out.println("我是子类构造函数");}
public static void main(String[] args){
new Z();
}
}
class X{
static{System.out.println("我是父类的静态代码块,我是最先执行的"); } //静态代码块
static C2 c= new C2(); //静态属性
{ System.out.println("我是父类初始化块,我的优先级和非静态属性一样,我们之间的顺序以代码顺序为准"); } //初始化块
Y b=new Y(); //非静态属性
X(){System.out.println("我是父类构造函数");}
}
class Y{
Y(){System.out.println("我是父类非静态属性,和具体的类实例相关,我可能在初始化块前执行也可能在其后");}
}
class Y2{
Y2(){System.out.println("我是子类非静态属性,和具体的类实例相关,我可能在初始化块前执行也可能在其后");}
}
class C{
C(){System.out.println("我是子类的一个静态属性(类变量),我和之前的初始化过程都是针对类的,与实例无关");}
}
class C2{
C2(){System.out.println("我是父类一个静态属性(类变量),我比子类的静态代码块执行的还早");}
}
#3
YXYZ
“实例化”一个类时先去把父类实例话,然后把成员变量初始化,然后再构造函数。
所以new Z()时先去实例化Z的父类X。在实例化X时,X没有父类,所以初始化成员Y,这时打印第一个Y,然后调用X的构造函数,这时打印X,
Z的父类实例完后就实例化Z的成员变量,只有一个成员变量Y,这时打印第二个Y,然后最后调用Z的构造函数,这时打印Z
“实例化”一个类时先去把父类实例话,然后把成员变量初始化,然后再构造函数。
所以new Z()时先去实例化Z的父类X。在实例化X时,X没有父类,所以初始化成员Y,这时打印第一个Y,然后调用X的构造函数,这时打印X,
Z的父类实例完后就实例化Z的成员变量,只有一个成员变量Y,这时打印第二个Y,然后最后调用Z的构造函数,这时打印Z
#4
谢谢各位,尤其是二楼的细心~~
#5
实例化一个类时,首先去实例化父类,再去实例化子类,类中的成员变量和构造函数,首先去初始化其成员变量,然后再执行构造函数。你可以做一下测试:
class X {
String str = this.getStr();
Y b = new Y();
X() {
System.out.print("X ");
}
String getStr(){
System.out.println("我要初始化成员变量");
return "0000";
}
}
class Y {
Y() {
System.out.print("Y ");
}
}
public class Z extends X {
Y y = new Y();
Z() {
System.out.print("Z ");
}
public static void main(String[] args) {
System.out.println("---------");
new Z();
}
}
class X {
String str = this.getStr();
Y b = new Y();
X() {
System.out.print("X ");
}
String getStr(){
System.out.println("我要初始化成员变量");
return "0000";
}
}
class Y {
Y() {
System.out.print("Y ");
}
}
public class Z extends X {
Y y = new Y();
Z() {
System.out.print("Z ");
}
public static void main(String[] args) {
System.out.println("---------");
new Z();
}
}
#6
不错,学习
#7
很好!
#8
恩,不错 ,仔细点分析还是能做对的。我为自己感到骄傲