您的位置:首页 > 职场人生

由一道Java面试题想到的(关于类初始化以及多态)(一)

2016-10-19 10:13 477 查看
public static Singleton singleton = new Singleton() ;

 昨天突然看到一道面试题,乍一看有点蒙,题目是这样的:

class Test1{

public static void main(String[] args) {

Singleton singleton = Singleton.getSingleton();
System.out.print(singleton.counter1);
System.out.print(",");
System.out.print(singleton.counter2);
}
}

class Singleton{

public static Singleton singleton = new Singleton() ;

public static int counter1;

public static int counter2 = 0;

public Singleton(){
counter1++;
counter2++;

}

public static Singleton getSingleton(){

return singleton;
}

}
读者们你们想一想,输出结果是什么?

------------------------------------------------------------------------------------------华丽丽的分割线------------------------------------------------------------------------------------------------------------------------

  这道题可以说很经典。乍一看,输出结果不就是1,1么?难道就这么简单题目会出现在中移动的面试题里面!!!!其实你再仔细想一想,这道题并非你想的那么简单。首先,你先看到类Singleton里面成员变量都华丽丽的被static修饰。这就要想一想在Java中static修饰符的作用。点击打开链接

   知道了static的作用之后,然后再看看一个类的初始化顺序。

  以下是讲解:

以下这段小程序对调用对象构造函数时,父类构造函数、成员变量初始化函数,以及非静态初始化块调用顺序进行验证,不考虑静态成员及静态初始化块。

public class Derive extends Base
{
private Member m1 = new Member("Member 1");
{
System.out.println("Initial Block()");
}

public Derive() {
System.out.println("Derive()");
}

private Member m2 = new Member("Member 2");
private int i = getInt();

private int getInt()
{
System.out.println("getInt()");
return 2;
}

public static void main(String[] args)
{
new Derive();
}
}

class Base
{
public Base()
{
System.out.println("Base()");
}
}

class Member
{
public Member(String m)
{
System.out.println("Member() "+m);
}
}
/*程序输出:
Base()
Member()  Member 1
Initial Block()
Member()  Member 2
getInt()
Derive()
*/

得出结论如下:不考虑静态成员的初始化,调用一个对象的构造函数时,程序先调用父类的构造函数(可以通过super关键字指定父类的构造函数,否则默认调用无参的构造函数,并且需要在子类的构造函数的第一行调用),之后静态成员变量的初始化函数和静态初始化块则按照在代码当中的顺序执行,成员变量如果没有指定值的话则赋予默认值,即基本数据类型为0或false等,对象则为null;最后调用自身构造函数。

好,至此,知道了初始化顺序,那么再回过头来看看这到面试题。在类Test1中,有这一句

Singleton singleton =Singleton.getSingleton();
       那么就要开始初始化类Singleton,首先静态static修饰的 

<span style="white-space:pre"> </span>public static Singleton singleton = new Singleton() ;
看到了new Singleton();那么就开始构造函数counter1++; --->counter1 == 1,counter2 == 1;
然后,public static cuonter1;就不会再执行,而public static counter2 = 0;会执行一次覆盖counter2;-->counter2 == 0;
最后执行public static getSingleton();返回对象singleton;所以最后得到的结果(1,0)。
由这里我又想到了在C++中虚函数,虚继承的时候类初始化的顺序的问题。明天再继续。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息