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

  • 相关阅读:
    django之验证码
    无法显示SQL Server Management Studio Express解决办法
    程序员常用不常见很难得的地址大全转
    调用ip138的页面获取IP地址
    VS 2010无法创建项目提示写入项目文件时出错 没有注册类别
    webapi token、参数签名是如何生成的(转载)
    尝试asp.net mvc 基于controller action 方式权限控制方案可行性(转载)
    委托学习
    Webapi上传数据(XML)敏感字符解决方案
    redis 学习
  • 原文地址:https://www.cnblogs.com/baby-zhude/p/8046457.html
Copyright © 2011-2022 走看看