java“块”的研究

本文重点关注静态块、非静态块、构造函数的加载顺序

直接上代码:

[java] view plaincopy

  1. package test.staticblock;
  2. public class A {
  3. /*父类构造方法*/
  4. public A(){
  5. System.out.println("A constructor");
  6. }
  7. /*父类静态块*/
  8. static
  9. {
  10. System.out.println("A static Block");
  11. }
  12. /*父类非静态块*/
  13. {
  14. System.out.println("A non-static Block");
  15. }
  16. /*父类静态方法*/
  17. public static void printStaticMethod(){
  18. System.out.println("A print Static Method");
  19. }
  20. /*父类普通方法*/
  21. public void printNormalMethod(){
  22. System.out.println("A print Normal Method");
  23. }
  24. }
  25. class B extends A{
  26. /*子类1构造方法*/
  27. public B(){
  28. System.out.println("B constructor");
  29. }
  30. /*子类1静态块*/
  31. static{
  32. System.out.println("B static Block");
  33. }
  34. /*子类1非静态块*/
  35. {
  36. System.out.println("B non-static Block");
  37. }
  38. /*子类1静态方法*/
  39. public static void printStaticMethod(){
  40. System.out.println("B print Static Method");
  41. }
  42. /*子类1普通方法*/
  43. public void printNormalMethod(){
  44. System.out.println("B print Normal Method");
  45. }
  46. }
  47. class C extends A{
  48. /*子类2构造方法*/
  49. public C(){
  50. System.out.println("C constructor");
  51. }
  52. /*子类2静态块*/
  53. static{
  54. System.out.println("C static Block");
  55. }
  56. /*子类2非静态块*/
  57. {
  58. System.out.println("C non-static Block");
  59. }
  60. /*子类2静态方法*/
  61. public static void printStaticMethod(){
  62. System.out.println("C print Static Method");
  63. }
  64. /*子类2没有override父类的普通方法*/
  65. }

 

[java] view plaincopy

  1. package test.staticblock;
  2. public class Test {
  3. public static void main(String[] args){
  4. A a1 = new B();
  5. A a2 = new C();
  6. a1.printStaticMethod();
  7. a1.printNormalMethod();
  8. a2.printStaticMethod();
  9. a2.printNormalMethod();
  10. }
  11. }

运行结果:

[plain] view plaincopy

  1. A static Block
  2. B static Block
  3. A non-static Block
  4. A constructor
  5. B non-static Block
  6. B constructor
  7. C static Block
  8. A non-static Block
  9. A constructor
  10. C non-static Block
  11. C constructor
  12. A print Static Method
  13. B print Normal Method
  14. A print Static Method
  15. A print Normal Method

根据结果分析:

顺序应该是这样的:父类Static->子类static->父类缺省{}->父类构造函数->子类缺省{}->子类构造函数


A static Block


父类静态块


B static Block


子类1静态块


A non-static Block


父类非静态块,缺省块


A constructor


父类构造函数


B non-static Block


子类1非静态块,缺省块


B constructor


子类1构造函数


C static Block


子类2静态块,由此可以看出static块仅在类加载时执行且仅执行一遍,因为A的静态块已经执行过了,这里不会再执行。


A non-static Block


父类非静态块,缺省块


A constructor


父类构造函数


C non-static Block


子类2非静态块,缺省块


C constructor


子类2构造函数


B print Static Method

B print Vitural Method

C print Static Method

A print Vitural Method

分析:当执行new B()和new C()时,它首先去看父类里面有没有静态代码块,如果有,它先去执行父类里面静态代码块里面的内容,当父类的静态代码块里面的内容执行完毕之后,接着去执行子类(自己这个类)里面的静态代码块,当子类的静态代码块执行完毕之后,它接着又去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法,这个就是一个对象的初始化顺序。

总结:对象的初始化顺序:首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容,当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法。总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。

注意:子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。如果父类没有不带参数的构造方法,那么子类必须用supper关键子来调用父类带参数的构造方法,否则编译不能通过。

重要一点:

static 块仅在类加载时,并非实例化时,被执行一遍,且在整个过程中只可能被执行一遍,这也就是在实例化C时

A a2 = new C();


A的static块没有被执行的原因。

但非静态块在实例化对象时总会被执行。

静态块一般用于初始化类中的静态成员;而非静态块一般用于初始化类中的非静态成员;

另外,非静态块是在创建对象时自动执行的代码。

 

时间: 2024-10-14 14:24:04

java“块”的研究的相关文章

JAVA 虚拟机深入研究(三)——Java内存区域

JAVA 虚拟机深入研究(一)--关于Java的一些历史 JAVA 虚拟机深入研究(二)--JVM虚拟机发展以及一些Java的新东西 JAVA 虚拟机深入研究(三)--Java内存区域 Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的围城,城外的人想进去,城里的人想出来. Java运行的时候会把内存分为若干个,他们各有各的用途,每块区域的创建和销毁都是相对独立的,有的跟虚拟机一起混,有的则抱着用户的大腿同生共死. 按照第七版的<Java虚拟机规范>规定,JVM所管理的内存包括以下

C#和Java交互相关研究

之前总觉得C#和Java可以交互应用,但是由于时间以及其他方面的原因,一直没有调研.今天抽空搜了一下,终于折腾出来了. 以下是我自己就C#和Java整合的一些提问和分析,如果有不对的地方,请路过的各位大虾给予指出.3Q! 问题来了: 1.C#和Java如何整合? 2.为什么C#(.Net)要和Java整合? 3.Java和C#整合时,Java主要扮演什么角色?C#扮演什么角色? 答案一一揭晓: 1.C#和Java整合大致有4条路可以走. 1.1 把Java包转换为DLL或者EXE后注册为com组

java 块语句 和引用类型

1.java中存在块语句,块语句分为四种 1.静态块 2.普通块 3.构造块 4.同步块 静态块的执行时机是在class文件装载的时候;静态块只会执行一次, 多个静态块的时候,按出现顺序执行,存放类的信息,用来在生成类之前进行的初始化,对一些static 变量赋值.如果某些代码必须要在项目启动时候就执行的时候,我们可以采用静态代码块,这种代码是主动执行的. 普通块存在于方法体中,用于设置变量的作用域, 构造块,初始对象信息,每创建一个对象,初始化一次,先于构造器执行 当一个类有很多个构造方法,每

山东xx大学计算机学院-关于 基于java作业的研究【原创】未经许可不得转载

闲暇之余,跟同学们探讨并研究了一下有关程序设计方面,利用Java面向对象的程序设计方法,设计学生成绩管理系统,以管理员身份登录,实现下列界面中常见的功能.贴部分图片 实现后,代码经过编译后,演示结果如下: 原文地址:https://www.cnblogs.com/qq2032333807/p/8179863.html

java源码研究--ArrayList实现

java.util.ArrayList是十分常用的容器之一,本文针对其常用方法,对其进行简单的研究.ArrayList常见方法如下,主要还是增删改查: 首先,看一下ArrayList中如何保存数据的: transient Object[] elementData; 所以,所有的数据都是保存在数组里的.当然,数组都有个大小: 若ArrayList使用无参构造函数实例化: ArrayList<Integer> arrayList = new ArrayList<Integer>();

要精通Java,先研究它的执行原理

对于任何一门语言,要想达到精通的水平,研究它的执行原理(或者叫底层机制)不失为一种良好的方式. 在本篇文章中,将重点研究java源代码的执行原理,即从程序员编写JAVA源代码,到最终形成产品,在整个过程中,都经历了什么?每一步又是怎么执行的?执行原理又是什么? 一.编写java源程序 java源文件:指存储java源码的文件. 先来看看如下代码: //MyTest被public修饰,故存储该java源码的文件名为MyTest public class MyTest { public static

LuaJ 调用java方法性能研究

先简单写一下: lua调用java的方法,在luaJ中有两种. 1 使用官方提供的luaJava库 local ins = luajava.newInstance( "com.test.lj.TestClass");ins:test() 2 自己绑定方法,采用类似原版lua的方式将方法 local ins = TestClass.new() --new方法自己绑定 ins:test() 哪种方法好? 结论: 令人惊讶的是,luajava库反射调用的性能在某些情况下,竟然比java原生绑

Java反射机制研究

以前听同时说反射很强大,看了一些相关文章今天把反射总结一下. 说明:反射主要用于开发框架,即制作框架: 一.获得Class对象 Class<?> c = Class.forName("classname");   抛出ClassNotFoundException 二.获得实现接口 Class<?> inters[] = c.getInterfaces(); for(int i=0;i<inters.length;i++){ System.out.print

Java反射API研究(4)——Class中的重要对象

一.Constructor与Method的父类:Executable Executable表示一个可执行类,构造方法与普通方法都是Executable AnnotatedType[] getAnnotatedExceptionTypes() AnnotatedType[] getAnnotatedParameterTypes() AnnotatedType getAnnotatedReceiverType() abstract AnnotatedType getAnnotatedReturnTy