`

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

阅读更多

对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序以此是(静态变量、静态初始化块)>(变量、初始化块)>构造器。我们可以通过下面的测试代码来验证这一点:<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面试题-类的初始化顺序.doc

    这个顺序表明,无论类之间的继承关系如何,初始化顺序始终是:静态变量和静态初始化块先于非静态成员。在创建对象时,父类的初始化先于子类。这是Java语言规范所规定的,确保在子类访问父类的静态或非静态成员时,...

    Java类继承初始化顺序

    总之,Java类继承初始化顺序涉及到静态和非静态初始化块、构造器的调用以及方法的覆盖。理解这些概念对于编写健壮的、易于维护的Java代码至关重要。在实际编程中,应合理利用继承特性,同时注意避免不必要的复杂性和...

    java程序初始化顺序

    在Java编程语言中,程序初始化的顺序是一个关键概念,它涉及到类加载、对象创建以及执行流程的安排。了解这些顺序对于编写高效、无错误的...在实际项目中,合理利用初始化顺序可以帮助我们优化资源加载,提高程序性能。

    对象初始化流程梳理对象初始化流程梳理

    Java中的对象初始化流程是编程实践中一个非常重要的概念,它涉及到类加载、静态初始化块、实例初始化块、构造器等多个方面。下面将详细解释这个过程。 首先,对象初始化流程的起点是程序的入口点,即`main`方法。当...

    Java初始化块Java初始化块.doc

    类的加载和初始化顺序: - 类加载:JVM首次主动使用某个类时,会进行类加载,包括类的验证、准备和解析阶段。 - 类初始化:在类初始化阶段,静态属性的内存被分配,然后执行静态初始化块来初始化静态属性。这个过程...

    JAVA面试题解惑系列——类的初始化顺序

    在Java中,类的初始化顺序是一个经常被问及的面试题目,尤其对于Java程序员和工程师来说,了解这个知识点是必须的。在Java中,类的初始化顺序是面试中的经典问题之一,它涉及到继承、静态成员以及实例成员等多个方面...

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

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

    java代码的初始化顺序demo

    总之,Java代码的初始化顺序是类加载的必然过程,涉及到静态和实例初始化块、构造函数、成员变量初始化以及继承关系的影响。这个demo是学习和理解这些概念的重要工具,通过实际操作可以加深对Java内存管理和对象生命...

    JAVA类的初始化顺序文.pdf

    子类 --构造器 这个输出揭示了在继承关系中类的初始化顺序: 1. **静态成员和静态初始化块**:首先,会按照父类到子类的顺序初始化静态变量和执行静态初始化块。在上面的例子中,"父类 --静态变量" 和 "子类 --静态...

    探究java的ClassLoader及类变量初始化顺序

    同时,掌握类变量初始化顺序可以避免因误解而导致的错误,特别是在多线程环境中,对静态变量的并发访问和初始化顺序的控制需要特别注意。 总之,深入理解Java的ClassLoader机制和类变量初始化顺序是提升Java编程...

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

    Java 类的初始化顺序是一个关键的编程概念,尤其对于理解和避免潜在的运行时错误至关重要。在 Java 中,类的元素初始化顺序遵循以下规则: 1. **静态变量与静态初始化块**: 首先,Java 解释器会执行类中的静态...

    C++和Java初始化顺序的比较代码

    在C++中,初始化顺序遵循以下规则: 1. 静态成员变量:无论它们在哪里定义,静态成员变量都按照声明的顺序初始化。 2. 非静态数据成员:在构造函数初始化列表中,成员变量按照它们在类声明中的顺序被初始化。即使...

    JAVA面试题解惑系列(一)——类的初始化顺序-JAVA程序员JAVA工程师面试必看.pdf,这是一份不错的文件

    在 JAVA 中,类的初始化顺序可以分为四个阶段:静态变量、静态初始化块、变量、初始化块和构造器。其中,静态变量和静态初始化块的初始化顺序是最高的,接着是变量和初始化块,最后是构造器。 在了解类的初始化顺序...

    类初始化和实例初始化1

    在Java编程语言中,类和实例的初始化是程序运行中的重要环节,对于理解和优化代码的执行效率至关重要。这里我们将深入探讨这两个概念。 首先,我们来看类的初始化过程,也称为类加载与初始化。当Java虚拟机(JVM)...

    JAVA面试题解惑系列类的初始化顺序JAVA程序员JAVA工程师面试必看.pdf

    Java语言中的类初始化顺序是面试中常见的问题,尤其对于Java程序员和工程师来说,理解这一概念至关重要。本篇文章将深入解析类初始化的顺序以及在继承情况下的表现。 首先,我们需要明确类初始化顺序的基本规则: ...

    JAVA面试题解惑系列(一)——类的初始化顺序-JAVA程序员JAVA工程师面试必看.pdf

    "子类--构造器"); } public static void main(String[] args) { new SubClass(); } } 当我们运行这段代码时,会看到以下输出...所以,对于Java程序员和工程师来说,掌握类的初始化顺序是非常基础且重要的知识点。

    深入理解java构造器机理

    “深入理解Java构造器机理” 在 Java 编程语言中,构造器是一...构造器是 Java 类中最重要的一个概念,用于初始化对象的创建。了解构造器的机理、执行顺序、作用及与其他概念的区别对于 Java 学习者和开发者非常重要。

    java 静态块实例块构造器调用

    Java编程语言中,类的初始化过程涉及到静态块(static block)、实例块(instance block)以及构造器(constructor)。这些块的执行顺序对于理解和编写复杂的Java程序至关重要,特别是在涉及继承关系时。下面我们将...

    Java初始化顺序1

    在上面的示例代码中,我们可以看到,类变量和实例变量的初始化顺序是按照定义的顺序进行的。同时,我们还可以看到,静态变量的初始化顺序是按照定义的顺序,并且只在第一次访问时初始化。 在 Java 中,static ...

Global site tag (gtag.js) - Google Analytics