JAVA面试题解惑系列——类的初始化顺序-JAVA程序员JAVA工程师面试必看.doc_第1页
JAVA面试题解惑系列——类的初始化顺序-JAVA程序员JAVA工程师面试必看.doc_第2页
JAVA面试题解惑系列——类的初始化顺序-JAVA程序员JAVA工程师面试必看.doc_第3页
JAVA面试题解惑系列——类的初始化顺序-JAVA程序员JAVA工程师面试必看.doc_第4页
JAVA面试题解惑系列——类的初始化顺序-JAVA程序员JAVA工程师面试必看.doc_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

-JAVA程序员JAVA工程师面试必看JAVA面试题解惑系列(一)类的初始化顺序关键字: java 面试题 初始化 作者:臧圩人(zangweiren) 网址: 转载请注明出处!(变量、初始化块)构造器。我们也可以通过下面的测试代码来验证这一点: Java代码 1. publicclassInitialOrderTest 2. 3. /静态变量 4. publicstaticStringstaticField=静态变量; 5. /变量 6. publicStringfield=变量; 7. 8. /静态初始化块 9. static 10. System.out.println(staticField); 11. System.out.println(静态初始化块); 12. 13. 14. /初始化块 15. 16. System.out.println(field); 17. System.out.println(初始化块); 18. 19. 20. /构造器 21. publicInitialOrderTest() 22. System.out.println(构造器); 23. 24. 25. publicstaticvoidmain(Stringargs) 26. newInitialOrderTest(); 27. 28. public class InitialOrderTest / 静态变量public static String staticField = 静态变量;/ 变量public String field = 变量;/ 静态初始化块static System.out.println(staticField);System.out.println(静态初始化块);/ 初始化块System.out.println(field);System.out.println(初始化块);/ 构造器public InitialOrderTest() System.out.println(构造器);public static void main(String args) new InitialOrderTest();运行以上代码,我们会得到如下的输出结果: 1. 静态变量 2. 静态初始化块 3. 变量 4. 初始化块 5. 构造器 这与上文中说的完全符合。那么对于继承情况下又会怎样呢?我们仍然以一段测试代码来获取最终结果: Java代码 1. classParent 2. /静态变量 3. publicstaticStringp_StaticField=父类-静态变量; 4. /变量 5. publicStringp_Field=父类-变量; 6. 7. /静态初始化块 8. static 9. System.out.println(p_StaticField); 10. System.out.println(父类-静态初始化块); 11. 12. 13. /初始化块 14. 15. System.out.println(p_Field); 16. System.out.println(父类-初始化块); 17. 18. 19. /构造器 20. publicParent() 21. System.out.println(父类-构造器); 22. 23. 24. 25. publicclassSubClassextendsParent 26. /静态变量 27. publicstaticStrings_StaticField=子类-静态变量; 28. /变量 29. publicStrings_Field=子类-变量; 30. /静态初始化块 31. static 32. System.out.println(s_StaticField); 33. System.out.println(子类-静态初始化块); 34. 35. /初始化块 36. 37. System.out.println(s_Field); 38. System.out.println(子类-初始化块); 39. 40. 41. /构造器 42. publicSubClass() 43. System.out.println(子类-构造器); 44. 45. 46. /程序入口 47. publicstaticvoidmain(Stringargs) 48. newSubClass(); 49. 50. class Parent / 静态变量public static String p_StaticField = 父类-静态变量;/ 变量public String p_Field = 父类-变量;/ 静态初始化块static System.out.println(p_StaticField);System.out.println(父类-静态初始化块);/ 初始化块System.out.println(p_Field);System.out.println(父类-初始化块);/ 构造器public Parent() System.out.println(父类-构造器);public class SubClass extends Parent / 静态变量public static String s_StaticField = 子类-静态变量;/ 变量public String s_Field = 子类-变量;/ 静态初始化块static System.out.println(s_StaticField);System.out.println(子类-静态初始化块);/ 初始化块System.out.println(s_Field);System.out.println(子类-初始化块);/ 构造器public SubClass() System.out.println(子类-构造器);/ 程序入口public static void main(String args) new SubClass();运行一下上面的代码,结果马上呈现在我们的眼前: 1. 父类-静态变量 2. 父类-静态初始化块 3. 子类-静态变量 4. 子类-静态初始化块 5. 父类-变量 6. 父类-初始化块 7. 父类-构造器 8. 子类-变量 9. 子类-初始化块 10. 子类-构造器 现在,结果已经不言自明了。大家可能会注意到一点,那就是,并不是父类完全初始化完毕后才进行子类的初始化,实际上子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。 那么对于静态变量和静态初始化块之间、变量和初始化块之间的先后顺序又是怎样呢?是否静态变量总是先于静态初始化块,变量总是先于初始化块就被初始化了呢?实际上这取决于它们在类中出现的先后顺序。我们以静态变量和静态初始化块为例来进行说明。 同样,我们还是写一个类来进行测试: Java代码 1. publicclassTestOrder 2. /静态变量 3. publicstaticTestAa=newTestA(); 4. 5. /静态初始化块 6. static 7. System.out.println(静态初始化块); 8. 9. 10. /静态变量 11. publicstaticTestBb=newTestB(); 12. 13. publicstaticvoidmain(Stringargs) 14. newTestOrder(); 15. 16. 17. 18. classTestA 19. publicTestA() 20. System.out.println(Test-A); 21. 22. 23. 24. classTestB 25. publicTestB() 26. System.out.println(Test-B); 27. 28. public class TestOrder / 静态变量public static TestA a = new TestA();/ 静态初始化块static System.out.println(静态初始化块);/ 静态变量public static TestB b = new TestB();public static void main(String args) new TestOrder();class TestA public TestA() System.out.println(Test-A);class TestB public TestB() System.out.println(Test-B);运行上面的代码,会得到如下的结果: 1. Test-A 2. 静态初始化块 3. Test-B 大家可以随意改变变量a、变量b以及静态初始化块的前后位置,就会发现输出结果随着它们在类中出现的前后顺序而改变,这就说明静态变量和静态初始化块是依照他们在类中的定义顺序进行初始化的。同样,变量和初始化块也遵循这个规律。 了解了继承情况下类的初始化顺序之后,如何判断最终输出结果就迎刃而解了。 10:13 浏览 (4106) 评论 (41) 分类: JAVA面试题解惑系列 收藏 相关推荐 评论zm2693450 2008-07-14 好贴,顶起来臧圩人 2008-07-08 回复 狂放不羁: 总结的很好,赞一个狂放不羁 2008-07-08 静态代码为什么先于非静态代码这是因为静态代码是在类加载完毕后执行的,而加载类的顺序是先父类后子类,所以静态代码的执行是先执行父类的,然后执行子类的。对于非静态变量以及实例初始化块都是在构造函数里的代码执行前执行。所以静态代码是在类加载后执行,而实例代码是在构造函数执行前执行。但是当我们显示控制类加载的时候情况有点变化,显示加载可以有关两种方法:第一种:利用forName方法当我们查API文档就会发现forName方法有两种形式。分别如下:public static Class forName(String className)throws ClassNotFoundExceptionpublic static Class forName(String name,boolean initialize,ClassLoader loader)throws ClassNotFoundException 第二个方法值得注意的就是第二个参数boolean initialize,如果我们把这个参数设置为false,那么当我们加载完类后就不会执行静态代码和静态的初始化动作。只有当我们new一个对象的时候才会初始化。而第三个参数是用来指明类的加载器的。如果查看java.lang.Class类的源代码,上述两种方法最终都会调用Class类中的私有的native方法forName0(),此方法的声明如下:private static native Class forName0(String name, boolean init , ClassLoader loader)throws ClassNotFoundException; 所以当我们调用Class.forName(name )时,其实是在方法内部调用了:forName0(name, true, ClassLoader.getCallerClassLoader();当我们调用Class.forName(name, initialize, loader )的时候,实际上此方法内部调用了:forName0(name, initialize, loader); 第二种:利用Class对象获取的ClassLoader装载。 此方法也是在实例化时才执行静态代码的执行。综上所述可以总结如下:1 对于隐式的加载(new一个对象和调用类的静态方法),静态代码是在类加载后立刻执行,而对于显示加载(第一种是用java.lang.Class的forName(String str)方法,第二种是用java.lang.ClassLoader的loadClass())就如同我上面所说,加载过程是可以由我们来控制的。2 实例化代码执行是载构造函数执行之前,涉及到继承时,父类的构造函数执行之前执行父类里的实例化代码,子类的构造函数执行之前执行子类的实例化代码。所以这样可以保证子类中用到的变量都是已经经过父类初始化的,从而保证了初始化的正确性。呵呵,这些是我学习J2SE的时候总结的,今天和大家分享。臧圩人 2008-07-06 回复Unmi: 你的建议很好 学习任何东西都有一个由浅入深的过程,能够掌握的广泛和深入固然好,不过有时候够用也是一个不错的标准Unmi 2008-07-06 实际上你理解了内存中的对象模型就用不着这样的长篇累椟,这也是java人相比与c+人员的一种缺陷,逃避了对内存,指针的感性理解,有些问题,譬如,转型,以及如上的类的初始化顺序反而把自己搞糊涂了。spiritfrog 2008-07-05 引用那么对于静态变量和静态初始化块之间、变量和初始化块之间的先后顺序又是怎样呢?是否静态变量总

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论