java初始化顺序-主要是final的说明
2017-08-23 11:50
267 查看
转自http://www.cnblogs.com/exspring/p/5315813.html
1、在任何事情发生之前,将分配给对象的存储空间初始化为0;
2、从根基类开始递归,按照类中的声明顺序调用静态代码块、静态成员的初始化方法。
但是有两个例外:
定义为final非静态基本数据类型的成员变量此时也会被初始化;
有且只有定义为final非静态的String成员变量,采用的“=”赋值初始化会被执行(非new)。我们知道java中没有
操作符重载这一概念,能通过“=”直接赋值的类只有String或Integer等java内部实现的final类。奇怪的是这里只有String能够初始化,
Integer等不行,具体只能看java虚拟机的实现了
![](http://images2015.cnblogs.com/blog/920546/201603/920546-20160324154452104-1244520096.png)
3、从根基类开始,按照类中的声明顺序调用非静态代码块和非静态成员(除了2中的几个final特例)初始化方法,再调用构造函数,然后向子类递归初始化;
注意:在父类构造函数内部调用具有多态行为的函数将导致无法预测的结果,因为此时会调用子类override后的方法,而此时所有子类的
非静态成员可能还没有初始化,不会得到我们想要的结果。
测试平台:win10(32) + jre1.8.0_73 + eclipse
测试代码:
基类
public class BaseInit {
static {
System.out.println("<<<基类静态代码块>>>");
}
public BaseInit() {
System.out.println("<<<基类构造函数>>>");
//调用子类的override函数,访问子类未初始化的非静态成员变量
dangerTest();
}
{
System.out.println("<<<基类非静态代码块>>>");
}
//need override
public void dangerTest() { }
}
子类:
public class DeriveInit extends BaseInit {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new DeriveInit();
}
/**
* 构造函数
*/
public DeriveInit() {
System.out.println("<<<子类构造函数>>>");
if(testNonStatic == 555)
{
System.out.println("成员变量已经初始化");
}
}
/**
* 静态
*/
static private int testStatic = 100;
static {
System.out.println("<<<子类静态代码块>>>");
if(testStatic == 100)
{
System.out.println("同一类内静态按照声明顺序初始化");
}
}
/**
* 非静态
*/
private int testNonStatic = 555;
{
System.out.println("<<<子类非静态代码块>>>");
if(testNonStatic == 555)
{
System.out.println("同一类内非静态按照声明顺序初始化");
}
}
/**
* 在基类中访问子类的非静态成员变量
*/
private int derive0 = 888;
final private int derive1 = 888;
final private Integer derive2 = 888;
final private String derive3 = new String("Hello World");
final private String derive4 = "Hello World";
@Override
public void dangerTest()
{
System.out.println("子类成员变量derive0 = " + derive0);
System.out.println("子类成员变量derive1 = " + derive1);
System.out.println("子类成员变量derive2 = " + derive2);
System.out.println("子类成员变量derive3 = " + derive3);
System.out.println("子类成员变量derive4 = " + derive4);
}
}
运行结果:
<<<基类静态代码块>>>
<<<子类静态代码块>>>
同一类内静态代码按照声明顺序初始化
<<<基类非静态代码块>>>
<<<基类构造函数>>>
子类成员变量derive0 = 0
子类成员变量derive1 = 888
子类成员变量derive2 = null
子类成员变量derive3 = null
子类成员变量derive4 = Hello World
<<<子类非静态代码块>>>
同一类内非静态代码按照声明顺序初始化
<<<子类构造函数>>>
成员变量已经初始化
--仅供参考,欢迎交流--
java初始化顺序
1、在任何事情发生之前,将分配给对象的存储空间初始化为0;2、从根基类开始递归,按照类中的声明顺序调用静态代码块、静态成员的初始化方法。
但是有两个例外:
定义为final非静态基本数据类型的成员变量此时也会被初始化;
有且只有定义为final非静态的String成员变量,采用的“=”赋值初始化会被执行(非new)。我们知道java中没有
操作符重载这一概念,能通过“=”直接赋值的类只有String或Integer等java内部实现的final类。奇怪的是这里只有String能够初始化,
Integer等不行,具体只能看java虚拟机的实现了
![](http://images2015.cnblogs.com/blog/920546/201603/920546-20160324154452104-1244520096.png)
3、从根基类开始,按照类中的声明顺序调用非静态代码块和非静态成员(除了2中的几个final特例)初始化方法,再调用构造函数,然后向子类递归初始化;
注意:在父类构造函数内部调用具有多态行为的函数将导致无法预测的结果,因为此时会调用子类override后的方法,而此时所有子类的
非静态成员可能还没有初始化,不会得到我们想要的结果。
测试平台:win10(32) + jre1.8.0_73 + eclipse
测试代码:
基类
public class BaseInit {
static {
System.out.println("<<<基类静态代码块>>>");
}
public BaseInit() {
System.out.println("<<<基类构造函数>>>");
//调用子类的override函数,访问子类未初始化的非静态成员变量
dangerTest();
}
{
System.out.println("<<<基类非静态代码块>>>");
}
//need override
public void dangerTest() { }
}
子类:
public class DeriveInit extends BaseInit {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new DeriveInit();
}
/**
* 构造函数
*/
public DeriveInit() {
System.out.println("<<<子类构造函数>>>");
if(testNonStatic == 555)
{
System.out.println("成员变量已经初始化");
}
}
/**
* 静态
*/
static private int testStatic = 100;
static {
System.out.println("<<<子类静态代码块>>>");
if(testStatic == 100)
{
System.out.println("同一类内静态按照声明顺序初始化");
}
}
/**
* 非静态
*/
private int testNonStatic = 555;
{
System.out.println("<<<子类非静态代码块>>>");
if(testNonStatic == 555)
{
System.out.println("同一类内非静态按照声明顺序初始化");
}
}
/**
* 在基类中访问子类的非静态成员变量
*/
private int derive0 = 888;
final private int derive1 = 888;
final private Integer derive2 = 888;
final private String derive3 = new String("Hello World");
final private String derive4 = "Hello World";
@Override
public void dangerTest()
{
System.out.println("子类成员变量derive0 = " + derive0);
System.out.println("子类成员变量derive1 = " + derive1);
System.out.println("子类成员变量derive2 = " + derive2);
System.out.println("子类成员变量derive3 = " + derive3);
System.out.println("子类成员变量derive4 = " + derive4);
}
}
运行结果:
<<<基类静态代码块>>>
<<<子类静态代码块>>>
同一类内静态代码按照声明顺序初始化
<<<基类非静态代码块>>>
<<<基类构造函数>>>
子类成员变量derive0 = 0
子类成员变量derive1 = 888
子类成员变量derive2 = null
子类成员变量derive3 = null
子类成员变量derive4 = Hello World
<<<子类非静态代码块>>>
同一类内非静态代码按照声明顺序初始化
<<<子类构造函数>>>
成员变量已经初始化
--仅供参考,欢迎交流--
相关文章推荐
- Java第11次作业:什么是继承?继承的好处?什么是覆写?super()?构造代码块?子父类初始化顺序? 抽象类能用final声明吗?final关键字声明类 方法 变量以及全局常量?抽象类的构造方法?
- 关于java初始化顺序的几点说明
- JAVA第七节-继承,继承中方法重写,继承的初始化顺序,final关键字,super关键字,object类
- java中的继承,继承中方法的重写,继承的初始化顺序,final关键字,super关键字
- java复用类(组合、继承,代理,final关键字,初始化顺序) 知识点的总结
- Java 类的实例变量初始化的过程 静态块、非静态块、构造函数的加载顺序
- java各种成员的初始化顺序
- 关于java方法的重载(Overloading),覆写(Override)以及final 方法的几点说明
- Java杂谈3——类加载机制与初始化顺序
- Thinking in java 读书笔记(四、toString,class的初始化顺序)
- java 初始化及执行顺序
- Java继承关系中类的初始化顺序
- JAVA 初始化顺序
- java继承情况下初始化顺序
- Java中的初始化顺序
- java继承中初始化的顺序
- JAVA对象的初始化顺序
- java 的初始化顺序
- java对象的初始化顺序
- java类的成员初始化顺序和初始化块知识