`

类中各属性的初始化顺序 ,构造器和初始化块

阅读更多

对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序以此是(静态变量、静态初始化块)>(变量、初始化块)>构造器。我们可以通过下面的测试代码来验证这一点:<wbr></wbr>

Java代码<wbr></wbr>

<wbr><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">运行以上代码,我们会得到如下的输出结果:<wbr></wbr></span></span><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">静态变量<wbr></wbr></span></span><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">静态初始化块<wbr></wbr></span></span><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">变量<wbr></wbr></span></span><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">初始化块<wbr></wbr></span></span><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">构造器<wbr></wbr></span></span><br><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">这与上文中说的完全符合。那么对于继承情况下又会怎样呢?我们仍然以一段测试代码来获取最终结果:<wbr></wbr></span></span><br><br><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">Java代码<wbr></wbr></span></span><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px"><wbr><wbr></wbr></wbr></span></span><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px"></span></span><textarea readonly name="code" class="java">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(); } } </textarea><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">运行一下上面的代码,结果马上呈现在我们的眼前:<wbr></wbr></span></span><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif"><span style="line-height:25px"><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">父类--静态变量<wbr></wbr></span></span><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">父类--静态初始化块<wbr></wbr></span></span><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">子类--静态变量<wbr></wbr></span></span><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">子类--静态初始化块<wbr></wbr></span></span><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">父类--变量<wbr></wbr></span></span><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">父类--初始化块<wbr></wbr></span></span><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">父类--构造器<wbr></wbr></span></span><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">子类--变量<wbr></wbr></span></span><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">子类--初始化块<wbr></wbr></span></span><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">子类--构造器</span></span><br></span></span><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">现在,结果已经不言自明了。大家可能会注意到一点,那就是,并不是父类完全初始化完毕后才进行子类的初始化,实际上子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。<wbr></wbr></span></span><br><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">那么对于静态变量和静态初始化块之间、变量和初始化块之间的先后顺序又是怎样呢?是否静态变量总是先于静态初始化块,变量总是先于初始化块就被初始化了呢?实际上这取决于它们在类中出现的先后顺序。我们以静态变量和静态初始化块为例来进行说明。<wbr></wbr></span></span><br><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">同样,我们还是写一个类来进行测试:<wbr></wbr></span></span><br><br><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">Java代码<wbr></wbr></span></span><br><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px"><wbr></wbr></span></span><span style="font-family:monospace; white-space:pre">class TestA {</span><textarea readonly name="code" class="java"><pre name="code" class="java"> public TestA() { System.out.println("Test--A"); } } class TestB { public TestB() { System.out.println("Test--B"); } } 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(); } }</pre></textarea><br><br><pre></pre> <textarea readonly name="code" class="java"><pre></pre></textarea><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">运行上面的代码,会得到如下的结果:<wbr></wbr></span></span><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">Test--A<wbr></wbr></span></span><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">静态初始化块<wbr></wbr></span></span><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">Test--B<wbr></wbr></span></span><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">大家可以随意改变变量a、变量b以及静态初始化块的前后位置,就会发现输出结果随着它们在类中出现的前后顺序而改变,这就说明静态变量和静态初始化块是依照他们在类中的定义顺序进行初始化的。同样,变量和初始化块也遵循这个规律。<wbr></wbr></span></span> <p><span style="color:rgb(50,62,50); font-family:simsun; font-size:14px; line-height:21px"><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">了解了继承情况下类的初始化顺序之后,如何判断最终输出结果就迎刃而解了</span></span></span></p> <p><span style="color:rgb(50,62,50); font-family:simsun; font-size:14px; line-height:21px"><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px"></span></span></span></p> <p><span style="color:rgb(50,62,50); font-family:simsun; font-size:14px; line-height:21px"><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px"></span></span></span></p> <p><span style="color:rgb(50,62,50); font-family:simsun; font-size:14px; line-height:21px"><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px">总结:</span></span></span></p> <p><span style="color:rgb(50,62,50); font-family:simsun; font-size:14px; line-height:21px"><span style="font-family:Helvetica,Tahoma,Arial,sans-serif; word-wrap:normal; word-break:normal; line-height:21px"><span style="word-wrap:normal; word-break:normal; line-height:25px"></span></span></span></p> <h2 style="color:black">1,构造器的语法格式</h2> <p></p> <p>修饰符:public private,protected,default</p> <p>类名:构造器的名字必须和类名一致</p> <p>参数列表</p> <h2 style="color:black">2,构造器的返回值类型</h2> <p>构造器不能定义返回值的类型,如果定义了返回值的类型,编译并不会报错,因为JVM已经把所谓的构造器当做是一个普通的方法.没有返回值类型并不是没有返回值,构造器有返回值的,返回的是当前类的对象,因此构造器的返回值类型总是当前类,因此没有定义返回值的类型.可以理解为构造器的返回值是隐式的.</p> <h2 style="color:black">3默认的构造器,</h2> <p>如果程序中没有显示的定义构造器,系统会默认的给程序一个无参的构造器.一旦加了构造器,默认的构造器就不存在了.</p> <h2 style="color:black"> <span style="color:red">4,</span>构造器是创建对象的重要途径<span style="color:red">,</span>是不是说构造器就完全负责创建对象呢<span style="color:red">?</span> </h2> <p>不是,构造器是创建对象的重要途径,同构new关键字来调用构造器也可以返回一个该类实例,但是这个过程并不是完全有构造器执行的.</p> <p>实际上,在系统调用构造器的时候,系统会先为该对象分配内存空间,为对象的成员变量赋初值,这个时候对象就已经产生了---这些操作都是在构造器的执行体之前执行的.也就是说,在构造器的执行体执行之前,对象就已经存在了,只是不能被外部的程序调用,构造体执行之后,对象就可以被外部的程序调用了.</p> <h2 style="color:black">5,构造器的重载</h2> <p><strong><span style="color:rgb(127,0,85)">public</span></strong><span style="color:black"></span><strong><span style="color:rgb(127,0,85)">class</span></strong><span style="color:black">ConstructorDemo {</span></p> <p><span style="color:black"></span><strong><span style="color:rgb(127,0,85)">private</span></strong><span style="color:black"></span><strong><span style="color:rgb(127,0,85)">int</span></strong><span style="color:black"></span><span style="color:rgb(0,0,192)">a</span><span style="color:black">;</span></p> <p><span style="color:black"></span></p> <p><span style="color:black"></span><strong><span style="color:rgb(127,0,85)">private</span></strong><span style="color:black">String</span><span style="color:rgb(0,0,192)">s</span><span style="color:black">;</span></p> <p><span style="color:black"></span></p> <p><span style="color:black"></span><strong><span style="color:rgb(127,0,85)">public</span></strong><span style="color:black">ConstructorDemo() {</span></p> <p><span style="color:black"></span>}</p> <p><span style="color:black"></span></p> <p><span style="color:black"></span><strong><span style="color:rgb(127,0,85)">public</span></strong><span style="color:black">ConstructorDemo(</span><strong><span style="color:rgb(127,0,85)">int</span></strong><span style="color:black">a ){</span></p> <p><span style="color:black"></span><strong><span style="color:rgb(127,0,85)">this</span></strong><span style="color:black">.</span><span style="color:rgb(0,0,192)">a</span><span style="color:black">= a;</span></p> <p><span style="color:black"></span>}</p> <p><span style="color:black"></span></p> <p><span style="color:black"></span><strong><span style="color:rgb(127,0,85)">public</span></strong><span style="color:black">ConstructorDemo (String s,</span><strong><span style="color:rgb(127,0,85)">int</span></strong><span style="color:black">a){</span></p> <p><span style="color:black"></span><strong><span style="color:rgb(127,0,85)">this</span></strong><span style="color:black">(a);</span></p> <p><span style="color:black"></span><strong><span style="color:rgb(127,0,85)">this</span></strong><span style="color:black">.</span><span style="color:rgb(0,0,192)">s</span><span style="color:black">= s;</span></p> <p><span style="color:black"></span>}</p> <p><span style="color:black">}</span></p> <h2 style="color:black">6,初始化块(代码块)</h2> <p>初始化块可以当做是Java程序里面的一种成员,代码块又分为:静态代码块和非静态的代码块,一个类中可以有多个代码块,代码块之间执行的顺序是根据代码块在程序中的位置来决定.静态的代码块总是比非静态的代码块先执行</p> <p>非静态代码块:可以把它当做是类的成员属性来理解.每次创建对象的时候都会执行一遍是属于成员变量</p> <p>静态的代码块:同样的可以把它理解成类变量,只有在加载类的时候才会执行.</p> <p>程序对属性进行初始化的顺序是<span style="color:red">:</span>代码块<span style="color:red">à</span>属性声明时候指定的初始值<span style="color:red">à</span>构造器中指定的值</p> <h2 style="color:black">7,初始化块和构造器</h2> <p>从某种程度上来讲,可以理解为初始化快是构造器的补充,因为初始化快总是在构造器之前执行,同样也可以对对象初始化.</p> <p>与构造器不同的是:初始化块只能执行一段固定的代码,不能够像构造器一样接受参数,而且是对类的所有的对象进行初始化.</p> <p><span style="color:red"></span>跟构造器一样的<span style="color:red">,</span>程序在执行的时候不仅会执行当前类的初始化快和构造器<span style="color:red">,</span>会一直追溯到<span style="color:red">object</span>类的初始化快和构造器<span style="color:red">.</span>先执行父类的初始化块和构造器<span style="color:red">(</span>先初始化块<span style="color:red">,</span>再构造器<span style="color:red">),</span>然后再执行当前类的初始化块和构造器<span style="color:red">.</span></p> <pre></pre> <pre></pre> <pre></pre> </wbr>

分享到:
评论

相关推荐

    java 静态非静态 字段方法 子类父类构造_初始化顺序!

    java 静态_非静态 字段_方法_代码块 子类父类构造_初始化顺序! 三个class 让你清清楚楚 第一个class java代码如下: package initialOrder; class Parent { // 静态变量 public static String p_StaticField...

    java面试题-类的初始化顺序.doc

    我们大家都知道,对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)&gt;(变量、初始化块)&gt;构造器。我们也可以通过下面的测试代码来验证这一点:

    java类中元素初始化顺序详解

    对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)&gt;(变量、初始化块)&gt;构造器

    深入理解java构造器机理

    java构造方法是java类中最重要的一个概念,这篇文档涵盖了,java对象初始化过程中构造器调用的顺序,及作用。

    JAVA面试题解惑系列

    我们大家都知道,对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)&gt;(变量、初始化块)&gt;构造器。我们也可以通过下面的测试代码来验证这一点:

    深入类的初始化和方法重载

     当然,C语言中不涉及到类的概念,但是,在C++和Java中,引入了构造器这种概念来解决这个问题。构造器是用来做初始化的工作的,如果程序员忘记在建类的时候加上构造器,则编译器会自动创建构造器。为了调用 方便,...

    powermock源码学习 支持模拟静态方法、构造函数、final类和方法、私有方法以及移除静态初始化器的模拟工具

    PowerMock的核心功能在于其能够通过提供定制的类加载器和应用一些字节码操作技巧,实现对静态方法、构造方法、私有方法和final方法的模拟。例如,在进行单元测试时,有时候我们并不希望测试数据进入实际的数据库,...

    杰普学习corejava总结笔记

    类加载,同时初始化类中静态的属性(赋默认值) 2.执行静态代码块 3.分配内存空间,同时初始化非静态的属性(赋默认值) 4.调用父类构造器(注意调用父类构造器之前已经给父类的非静态的属性显示赋值,如果有显示赋值的话...

    Java初始化对象的工具 – 构造器

    写在前面:博主是一只经过实战开发历练后投身培训事业的“小山猪”,昵称取自动画片《狮子王》中的“彭彭”,总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘...

    java基础核心总结归纳---参考手册--心得手册-学习资料-总结经验

    构造器初始化 15 初始化顺序 16 this 和 super 16 访问控制权限 16 继承 17 多态 17 代理 17 Static 17 Final 17 接⼝和抽象类 18 接⼝ 18 抽象类 18 异常 18 认识 Exception 18 什么是 Throwable 18 常⻅的 ...

    c# 9.0新特性——模块初始化器

    在库加载的时候,能以最小的开销、无需用户显式调用任何接口,使客户做一些期望的和一次性的初始化。 当前静态构造函数方法的一个最大的问题是运行时会对带有静态构造函数的类型做一些额外的检查。这是因为要决定...

    c# 类型构造器

    主要作用是:设置类型中静态字段的初始化。类型构造器不一定要在类中定义,但是最多也只能有一个。例: 代码如下: class SomeType{ static SomeType(){} } jit编译器在编译一个方法时,会查看代码引用哪些类型。任何...

    Java 基础核心总结 +经典算法大全.rar

    类的初始化 成员初始化 构造器初始化初始化顺序 数组初始化 对象的销毁 对象作用域 this 和 super 访问控制权限继承 多态组合代理 向上转型static final 接口和抽象类接口 抽象类异常 认 识 Exception 什么是 ...

    关于JVM的总结

    初始化:在准备阶段已经赋过一个系统要求的初始值,而在初始化阶段则通过程序制定的主管计划去初始化变量和其他资源,从另一个角度理解就是 执行类构造器的()方法 .()方法是由编译器自动收集类中的所有变量的复制动作和...

    编程思想下篇

    5.7 构造器初始化 5.7.1 初始化顺序 5.7.2. 静态数据的初始化 5.7.3. 显式的静态初始化 5.7.4. 非静态实例初始化 5.8 数组初始化 5.8.1 可变参数列表 5.9 枚举类型 5.10 总结 第6章 访问权限控制 第7章 复用类 第8章...

    Thinking in java4(中文高清版)-java的'圣经'

    5.6.1 指定初始化 5.7 构造器初始化 5.7.1 初始化顺序 5.7.2. 静态数据的初始化 5.7.3. 显式的静态初始化 5.7.4. 非静态实例初始化 5.8 数组初始化 5.8.1 可变参数列表 5.9 枚举类型 5.10 总结 第6章 访问权限控制 ...

    疯狂JAVA讲义

    5.9.2 初始化块和构造器 161 5.9.3 静态初始化块 162 5.10 本章小结 165 本章练习 165 第6章 面向对象(下) 166 6.1 基本数据类型的包装类 167 6.2 处理对象 170 6.2.1 打印对象和toString方法 170 6.2.2 =...

    Java的六大问题你都懂了吗

    例如我们要在构造器中对一个名叫s的String引用变量进行初始化,把它设置为初始值,应当这样做:  public class Demo {  private String s;  public Demo {  s = "Initial Value";}  }  而非  s = new ...

    Java编程思想?初始化与清理

     需要重载的一个重要原因是,因为我们的构造器只能有一个名字,也是和类名相同.但是如果我们需要通过不同的方式去构造一个对象的时候我们该如何是好?那么这里需要通过对构造器的重载来实现.这样需要多个构造器来...

Global site tag (gtag.js) - Google Analytics