zoukankan      html  css  js  c++  java
  • 类的初始化与实例化:

    类的实例化顺序:先是类初始化(执行类的静态初始化块),再是实例初始化(执行类的普通初始化块、构造器)

    类初始化的顺序是:java.lang.Object类--->中间的父类......--->当前初始化的类(先执行最顶层父类的静态初始化块,然后依次向下,直到执行当前类的静态初始化块)

    实例初始化的顺序是:java.lang.Object类--->中间的父类......--->当前初始化的类(先执行最顶层父类的普通初始化块、最顶层父类的构造器,然后依次向下,直到执行当前类的普通初始化块、当前类的构造器)

    代码实例如下:

    import static java.lang.System.*;
    class Root{
    	static{
    		out.println("Root类静态初始化块!");
    	}
    
    	{
    		out.println("Root类普通初始化块!");
    	}
    	
    	public Root(){
    		out.println("Root类无参数构造器!");
    	}
    }
    
    class Mid extends Root{
    	static{
    		out.println("Mid类静态初始化块!");
    	}
    
    	{
    		out.println("Mid类普通初始化块!");
    	}
    
    	public Mid(){
    		out.println("Mid类无参数构造器!");
    	}
    
    	public Mid(String name){
    		out.println("Mid类一个参数的构造器:name="+name);
    	}
    }
    
    class Leaf extends Mid{
    	static{
    		out.println("Leaf类静态初始化块!");
    		out.println();
    	}
    
    	{
    		out.println("Leaf类普通初始化块!");
    	}
    
    	public Leaf(){
    		out.println("Leaf类无参数构造器!");
    	}
    }
    
    public class Test{
    	public static void main(String[] args){
    		Leaf leaf=new Leaf();
    	}
    }
    

     运行结果:

    从结果可以看出,结果前三行为类初始化阶段执行的两个父类和自己类中的静态初始化块,后六行为类实例化阶段执行的两个父类和自己类中的普通静态初始化块、构造器。

    把代码稍微改造一下,仔细体会其中的调用顺序变化:

    import static java.lang.System.*;
    class Root{
    	static{
    		out.println("Root类静态初始化块!");
    	}
    
    	{
    		out.println("Root类普通初始化块!");
    	}
    	
    	public Root(){
    		out.println("Root类无参数构造器!");
    	}
    }
    
    class Mid extends Root{
    	static{
    		out.println("Mid类静态初始化块!");
    	}
    
    	{
    		out.println("Mid类普通初始化块!");
    	}
    
    	public Mid(){
    		out.println("Mid类无参数构造器!");
    	}
    
    	public Mid(String name){
    		//-改动:调用本类构造器
    		this();
    		out.println("Mid类一个参数的构造器:name="+name);
    	}
    }
    
    class Leaf extends Mid{
    	static{
    		out.println("Leaf类静态初始化块!");
    		out.println();
    	}
    
    	{
    		out.println("Leaf类普通初始化块!");
    	}
    
    	public Leaf(){
    		//-改动:调用父类一个参数构造器
    		super("张三");
    		out.println("Leaf类无参数构造器!");
    	}
    }
    
    public class Test{
    	public static void main(String[] args){
    		Leaf leaf=new Leaf();
    	}
    }
    

     运行结果:

    对Leaf类二次实例化:

    import static java.lang.System.*;
    class Root{
    	static{
    		out.println("Root类静态初始化块!");
    	}
    
    	{
    		out.println("Root类普通初始化块!");
    	}
    	
    	public Root(){
    		out.println("Root类无参数构造器!");
    	}
    }
    
    class Mid extends Root{
    	static{
    		out.println("Mid类静态初始化块!");
    	}
    
    	{
    		out.println("Mid类普通初始化块!");
    	}
    
    	public Mid(){
    		out.println("Mid类无参数构造器!");
    	}
    
    	public Mid(String name){
    		//-改动:调用本类构造器
    		this();
    		out.println("Mid类一个参数的构造器:name="+name);
    	}
    }
    
    class Leaf extends Mid{
    	static{
    		out.println("Leaf类静态初始化块!");
    		out.println();
    	}
    
    	{
    		out.println("Leaf类普通初始化块!");
    	}
    
    	public Leaf(){
    		//-改动:调用父类一个参数构造器
    		super("张三");
    		out.println("Leaf类无参数构造器!");
    		out.println();
    	}
    }
    
    public class Test{
    	public static void main(String[] args){
    		Leaf leaf1=new Leaf();
    		Leaf leaf2=new Leaf();//-二次改动,第二次实例化
    	}
    }
    

     运行效果:

    总结:

    1、Java加载并初始化某个类时,总是保证该类所有父类(包括直接和间接)全部加载并初始化

    2、如上效果所示:类初始化成功后,会在虚拟机里一直存在,因此当第二次实例化时,不会再进行类初始化了

  • 相关阅读:
    Mach-O iOS
    IPA的构建原理 iOS
    输入网址进入网页按回车刷新网页都发生了什么?URL 输入到显示的过程?
    LeetCode另一棵树的子树Swift
    如何解决静态库的冲突问题 iOS
    LeetCode下一个更大元素 I Swift -- 单调递增栈
    UITapGestureRecognizer 和 UICollectionView/UITableView等点击事件冲突问题
    UITableView/UICollectionView调用reloadData刷新时界面闪烁
    C#绘制折线图或曲线图,直接返回Image对象或图片文件
    C#反射+继承+接口的应用
  • 原文地址:https://www.cnblogs.com/baby-zhude/p/8046457.html
Copyright © 2011-2022 走看看