实例化子类之后发生了什么

当我们用SuperClass s=new SubClass()实例化一个子类对象时,发生了什么。首先我们要知道类加载的机制,这是一切实例化的基础。
classloader 加载类用的是全盘负责委托机制。
全盘负责:即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的所有 Class也由这个classloader负责载入,除非是显式的使用另外一个classloader载入
委托机制:先让parent(父)类加载器 (而不是super,它与parent classloader类不是继承关系)寻找,只有在parent找不到的时候才从自己的类路径中去寻找。
类加载还采用了cache机制:如果 cache中保存了这个Class就直接返回它,如果没有才从文件中读取和转换成Class,并存入cache,这就是为什么修改了Class但是必须重新启动JVM才能生效的原因。
1. 检测此Class是否载入过(即在cache中是否有此Class),如果有到8,如果没有到2
2. 如果parent classloader不存在(没有parent,那parent一定是bootstrap classloader了),到4
3. 请求parent classloader载入,如果成功到8,不成功到5
4. 请求jvm从bootstrap classloader中载入,如果成功到8
5. 寻找Class文件(从与此classloader相关的类路径中寻找)。如果找不到则到7.
6. 从文件中载入Class,到8.
7. 抛出ClassNotFoundException.
8. 返回Class.
按照以上规则,我们看如下代码:
	class SuperClass {
	    public SuperClass() {
	        System.out.println("SuperClass of constructor");
	        m();
	        this.showname();
	    }
	    protected void m() {
	        System.out.println("SuperClass.m()");
	    }
	    protected void showname(){
	    	System.out.println("now is "+this.getClass());
	    }
	}
	public class SubClass extends SuperClass  {
	    private int i = 10;
	    public SubClass() {
	    	super.m();
	        System.out.println("SubClass of constructor");
	       // super.m();
	        m();
	    }
	    public void m() {
	        System.out.println("SubClass.m(): i = " + i);
	    }
	    private void m(int a){	    	
	    }    
	    public void showname(){
	    	System.out.println("son father is "+super.getClass());
	    	System.out.println("son is "+this.getClass());
	    }
<span style="white-space:pre">	</span>    public static void main(String[] args) {
<span style="white-space:pre">	</span>        SuperClass t = new SubClass();
<span style="white-space:pre">	</span>    }
<span style="font-family: Arial;">	}</span>
当我们实例化SubClass时,JVM会加载相关的类,包括子类,父类并保留父子关系。此时方法子类中的同名同参数列表方法m()实际上是对父类进行了重写。实例化顺序如下,父类中static—子类中static—父类中默认初始化—父类构造函数—子类默认初始化—子类构造函数。在这个过程中,任何对m()方法的合理调用都会调用子类的方法,即已经重写后的方法。除非super.m()调用,才会调用到父类的m方法,原因就是该方法已经被子类m覆盖。
this变量指向当前执行程序的对象,由于本程序实例化子类对象,所以所有this指向子类对象,父类中的this调用,会调用子类的方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值