区别类方法、实例方法和字段的调用

http://www.javaeye.com/topic/368796

 

本例根据一个实例来说明类方法和实例方法调用的区别,以及不同修饰符下的属性调用的区别,并对这种区别作出解释。
     父类定义:

Java代码 复制代码
  1. public class Parent{   
  2.     public static String name = "父类的名字,静态常量";   
  3.     public final int age = 40;   
  4.     public String birth = "父类生日,变量";   
  5.     public static void sayHello(){   
  6.         System.out.println("父类的类方法,Hello Parent~");   
  7.     }   
  8.     public void sayBye(){   
  9.         System.out.println("父类的实例方法,Bye Parent~");   
  10.     }   
  11. }  
public class Parent{
	public static String name = "父类的名字,静态常量";
	public final int age = 40;
	public String birth = "父类生日,变量";
	public static void sayHello(){
		System.out.println("父类的类方法,Hello Parent~");
	}
	public void sayBye(){
		System.out.println("父类的实例方法,Bye Parent~");
	}
}


     子类定义:

Java代码 复制代码
  1. public class Son extends Parent{   
  2.     public static String name = "子类名字,静态变量";   
  3.     public final int age = 20;   
  4.     public String birth = "子类生日,变量";   
  5.   
  6.     public static void sayHello(){   
  7.         System.out.println("子类的类方法,Hello Child!");   
  8.     }   
  9.     public void sayBye(){   
  10.         System.out.println("子类的实例方法,Bye Child!");   
  11.     }   
  12.     public static void main(String[] args){   
  13.         //1   
  14.         Parent obj1 = new Son();   
  15.         System.out.println(obj1.name);   
  16.         System.out.println(obj1.age);   
  17.         System.out.println(obj1.birth);   
  18.         obj1.sayHello();   
  19.         obj1.sayBye();   
  20.     }   
  21. }  
public class Son extends Parent{
	public static String name = "子类名字,静态变量";
	public final int age = 20;
	public String birth = "子类生日,变量";

	public static void sayHello(){
		System.out.println("子类的类方法,Hello Child!");
	}
	public void sayBye(){
		System.out.println("子类的实例方法,Bye Child!");
	}
	public static void main(String[] args){
		//1
		Parent obj1 = new Son();
		System.out.println(obj1.name);
		System.out.println(obj1.age);
		System.out.println(obj1.birth);
		obj1.sayHello();
		obj1.sayBye();
	}
}


输出结果:
  

引用

父类的名字,静态常量
40
父类生日,变量
父类的类方法,Hello Parent~
子类的实例方法,Bye Child


    
      主函数中声明了对Parent的引用obj1,这个引用指向Son的对象,即实际对象是利用new Son()所创建的实例。
      上例中,obj1对调用了Parent类的静态方法sayHello(),而调用了Son类的实例方法sayHello()。对类方法和实例方法调用的区别,《深入Java虚拟机》中有这样一段话可以解释:

引用
当JVM调用一个类方法时,它会基于对象引用的类型(通常在编译时可知)来选择所调用的方法。相反,当JVM调用一个实例方法是,它会基于实际对象的类(只能在运行时得知)来选择所调用的方法。


对象引用obj1的类型Parent自加载进入JVM之后便在内存的方法区维护了静态方法,而Son类的实例方法sayBye()是在被实际对象调用的时候才动态连接的。
      基于上面分析可以推测,因为类在方法区中还维护了字段信息、类(静态)变量、常量池,JVM调用一个字段时,它将基于对象引用的类型来选择所调用的字段,故obj1调用的字段皆来自于父类Parent。

注:常量池:常量池就是该类型所用常量的一个有序集合,包括直接常量(string、integer和floating point常量)和对其他类型、字段和方法的符号引用。池中的数据项就像数组一样是通过索引访问的,因为常量池存储了相应类型所用到的所有类型、字段和方法的符号引用,所以他在java程序的动态连接性中起到核心作用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值