由一道Java面试题想到的(关于类初始化以及多态)(一)
2016-10-19 10:13
477 查看
public static Singleton singleton = new Singleton() ;
昨天突然看到一道面试题,乍一看有点蒙,题目是这样的:
------------------------------------------------------------------------------------------华丽丽的分割线------------------------------------------------------------------------------------------------------------------------
这道题可以说很经典。乍一看,输出结果不就是1,1么?难道就这么简单题目会出现在中移动的面试题里面!!!!其实你再仔细想一想,这道题并非你想的那么简单。首先,你先看到类Singleton里面成员变量都华丽丽的被static修饰。这就要想一想在Java中static修饰符的作用。点击打开链接
知道了static的作用之后,然后再看看一个类的初始化顺序。
以下是讲解:
以下这段小程序对调用对象构造函数时,父类构造函数、成员变量初始化函数,以及非静态初始化块调用顺序进行验证,不考虑静态成员及静态初始化块。
得出结论如下:不考虑静态成员的初始化,调用一个对象的构造函数时,程序先调用父类的构造函数(可以通过super关键字指定父类的构造函数,否则默认调用无参的构造函数,并且需要在子类的构造函数的第一行调用),之后静态成员变量的初始化函数和静态初始化块则按照在代码当中的顺序执行,成员变量如果没有指定值的话则赋予默认值,即基本数据类型为0或false等,对象则为null;最后调用自身构造函数。
好,至此,知道了初始化顺序,那么再回过头来看看这到面试题。在类Test1中,有这一句
<span style="white-space:pre"> </span>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++中虚函数,虚继承的时候类初始化的顺序的问题。明天再继续。
相关文章推荐
- 由一道面试题所想到的--Java实例变量初始化
- 由一道面试题所想到的--Java实例变量初始化
- 一道关于java线程的面试题
- Java的一道面试题----静态变量初始化过程
- java面试题inti=2;i+=i-=i*i的值以及关于i++;++i;i=i+1;i+=1 的效率问题
- 一道关于Java中Integer缓冲区的面试题
- 展讯的一道笔试Java题(关于静态初始化问题)
- 一道关于截取字符串的java面试题
- 一道阿里巴巴笔试题中,关于java中的变量,初始化快,构造函数初始化分析
- 一道Java初始化面试题
- 关于面试题java内存泄漏想到的(1)
- 关于一道简单的Java 基础面试题的剖析: short s1=1;s1 = s1 +1会报错吗?
- 一道关于java 类初始化 成员初始化的笔试题的解析
- 关于一道简单的Java 基础面试题的剖析: short s1=1;s1 = s1 +1会报错吗?
- 一道关于静态变量的初始化顺序面试题
- 关于JAVA的一道面试题
- 关于一道java面试题的分析
- 关于一道简单的Java 基础面试题的剖析: short s1=1;s1 = s1 +1会报错吗?
- 关于继承、组合、多态的一道面试题
- 关于一道简单的Java 基础面试题的剖析: short s1=1;s1 = s1 +1会报错吗?