浅谈java类中成员的初始化顺序(一)

类被创建之后的成员的初始化顺序到底是怎么样的?

首先 不考虑继承


package com;

public class DemoOne {    /**     * 关于类的初始化顺序     */    //不考虑继承结构的情况    private static int a=1;    private String  str="我被赋值了";    static{        //为什么static成员函数不能访问非static变量, 不能调用非static成员函数?        //静态代码块独立于对象而存在 不依赖于对象存在 简单来说可以直接以类型名调用DemoOne.a        //而成员变量的存在依赖于对象的创建才能被调用        //所以, static成员不能访问非static变量, 不能调用非static成员!        //  编译报错     System.out.println("str ===="+ str);        System.out.println("1 静态变量被赋初始值 a===="+a);        System.out.println("2 进入静态块");    }

{        System.out.println("3 成员变量被赋值  str ===="+ str);        System.out.println("4 进到普通代码块");    }
public void run(){    System.out.println(" 进入普通方法");}public  static void go(){    System.out.println(" 进入静态方法");}
    public DemoOne(){        System.out.println("5 进入构造器");    }

public static void main(String[] args) {        new  DemoOne();    }

}
 

运行程序后输出结果为:

1 静态变量被赋初始值 a====1
2 进入静态块
3 成员变量被赋值 str ====我被赋值了
4 进到普通代码块
5 进入构造器

为了验证静态成员的顺序由代码的前后顺序决定 加入第二个静态块

package com;

public class DemoOne {
    static{
        System.out.println("1 进入第一个静态代码块");
    }
    private static int a;
    static{
        System.out.println("2 进入第二个静态块");
    }
public static void main(String[] args) { new DemoOne(); } }

输出结果为:

1 进入第一个静态代码块
2 进入第二个静态块

由输出结果可以看到 调整顺序后的静态块先后顺序发生改变

总结一下 不考虑继承的类的成员加载顺序依次为 静态变量和常量->顺序位的静态块->普通成员变量->普通代码块->构造器

下面考虑存在父类的情况

package com;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class Demo {
    /**
     *
     * @param args
     */
    private static int a=1;
    private String  str="我在父类被赋值了";
    static{
        System.out.println("1 父类静态变量被赋初始值 a===="+a);
        System.out.println("2 进入父类静态块");
    }
    {
        System.out.println("5  父类成员变量被赋值  str ===="+ str);
        System.out.println("6  进入父类普通代码块");
    }
    public Demo(){
        System.out.println("7 进入父类构造器");
    }
}

子类

package com;

public class DemoOne  extends Demo{
    private static int a=1;
    private String  str="我在子类被赋值了";
    static{
        System.out.println("3 子类静态变量被赋初始值 a===="+a);
        System.out.println("4 进入子类静态块");
    }
    {
        System.out.println("8  子类成员变量被赋值  str ===="+ str);
        System.out.println("9  进入子类普通代码块");
    }
    public DemoOne(){
        System.out.println("10 进入子类构造器");
    }
    public static void main(String[] args) {
        new  DemoOne();
    }

}

输出结果为:

1 父类静态变量被赋初始值 a====1
2 进入父类静态块
3 子类静态变量被赋初始值 a====1
4 进入子类静态块
5 父类成员变量被赋值 str ====我在父类被赋值了
6 进入父类普通代码块
7 进入父类构造器
8 子类成员变量被赋值 str ====我在子类被赋值了
9 进入子类普通代码块
10 进入子类构造器

所以存在父类的情况下 类成员的初始化顺序

父类静态变量->父类静态块->子类静态变量->子类静态块->父类成员变量->父类普通代码块->父类构造器->子类成员变量->子类普通代码块->子类构造器

还在学习总结过程中,如若有误,请看到的朋友及时指出。

原文地址:https://www.cnblogs.com/tongAngle/p/10128133.html

时间: 2024-10-14 10:37:54

浅谈java类中成员的初始化顺序(一)的相关文章

java类中成员变量初始化后存放在堆内存中还是栈内存中?

答案是堆内存. 之前明明看过java类初始化过程的, 但一下子看到这样的题目,还是懵了. 百度后,那些帖子的回复各有各说, 脑袋都看得要塞住了,还是看书求证吧. 李刚的<疯狂Java>第128页开始,有一个类从初始化开始, 在内存发生什么变化的详细过程,这里简单记录一下. class Person{     String name;     static int eyeNum; } 上面这个Person类,有成员变量name和静态成员变量eyeNum了, 当执行下面语句: Person p1 

Java 类中成员初始化顺序

Java 中的类成员 基本分为 静态成员, 实例变量  方法中特别的是静态方法和构造方法. 1.定义一个类 public class ClassLoaderTest { public int a ; public String b; private static int c; public  ClassLoaderTest(){ System.out.println("执行前:"+ a + "  "+ b); a = 10; b = "lisi"

浅谈java类集框架和数据结构(2)

继续上一篇浅谈java类集框架和数据结构(1)的内容 上一篇博文简介了java类集框架几大常见集合框架,这一篇博文主要分析一些接口特性以及性能优化. 一:List接口 List是最常见的数据结构了,主要有最重要的三种实现:ArrayList,Vector,LinkedList,三种List均来自AbstracList的实现,而AbstracList直接实现了List接口,并拓展自AbstractCollection. 在三种实现中,ArrayList和Vector使用了数组实现,可以认为这两个是

浅谈Java 8中的方法引用(Method References)

本人接触Java 8的时间不长,对Java 8的一些新特性略有所知.Java 8引入了一些新的编程概念,比如经常用到的 lambda表达式.Stream.Optional以及Function等,让人耳目一新.这些功能其实上手并不是很难,根据别人的代码抄过来改一下,并不要知道内部的实现原理,也可以很熟练地用好这些功能.但是当我深究其中一些细节时,会发现有一些知识的盲区.下面我就来谈一下Java 8中的Method References这个概念. 首先我给出官方对于这一概念的详细解释,https:/

Java类、实例的初始化顺序

题目: public class InitTest{ public static int k = 0; public static InitTest t1 = new InitTest("t1"); public static InitTest t2 = new InitTest("t2"); public static int i = print("i"); public static int n = 99; public int j = pr

浅谈Listener、Filter、Servlet初始化顺序

Listener.Filter.Servlet都有一个初始化的过程,对应的方法分别为: contextInitialized(ServletContextEvent arg0); // Listener init(FilterConfig filterConfig); // Filter init(ServletConfig config); // Servlet 那么它们的初始化顺序是什么呢? Listener > Filter > Servlet TestServlet.java: pac

浅谈Java泛型中的extends和super关键字(转)

泛型是在Java 1.5中被加入了,这里不讨论泛型的细节问题,这个在Thinking in Java第四版中讲的非常清楚,这里要讲的是super和extends关键字,以及在使用这两个关键字的时候为什么会不同的限制.    首先,我们定义两个类,A和B,并且假设B继承自A.下面的代码中,定义了几个静态泛型方法,这几个例子随便写的,并不是特别完善,我们主要考量编译失败的问题: public class Generic{ //方法一 public static <T extends A> void

浅谈Java泛型中的extends和super关键字

泛型是在Java 1.5中被加入了,这里不讨论泛型的细节问题,这个在Thinking in Java第四版中讲的非常清楚,这里要讲的是super和extends关键字,以及在使用这两个关键字的时候为什么会不同的限制.  首先,我们定义两个类,A和B,并且假设B继承自A. package com.wms.test; import java.util.ArrayList; import java.util.List; public class Generic { public static void

浅谈C++类中的static

静态成员是可以独立访问的,也就是说,无须创建任何对象实例就可以访问,而静态成员函数可不建立对象就可以被使用.或者说静态函数与一般函数没有太大的区别,只是访问有限制,静态变量跟一般的全局变量的区别就是访问有限制. static变量 static变量不像普通的变量,static变量独立于一切类对象处在.static修饰的变量先于对象存在,所以static修饰的变量要在类外初始化.因为static是所有对象共享的东西嘛,必须要比对象先存在的. class test { private: public: