码迷,mamicode.com
首页 > 其他好文 > 详细

test

时间:2018-09-17 00:05:58      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:invoke   因此   ati   编译器   方法调用   有关   import   test   先来   

我们先来看一下下面的例子:

package demo.jvm.test8?

public class Demo2 {

/**

  • 方法静态分派演示
  • @author zzm

*/

static abstract class Human {

}

 

static class Man extends Human {

}

 

static class Woman extends Human {

}

 

public void sayHello(Human guy) {

System.out.println("hello,guy")?

}

 

public void sayHello(Man guy) {

System.out.println("hello,gentleman")?

}

 

public void sayHello(Woman guy) {

System.out.println("hello,lady")?

}

public static void main(String[] args) {

Human man = new Man()?

Human woman = new Woman()?

Demo2 sr = new Demo2()?

sr.sayHello(man)?

sr.sayHello(woman)?

 

}

}

结果:

hello,guyhello,guy

package demo.jvm.test8?

import demo.jvm.test8.Demo6.Man? import demo.jvm.test8.Demo6.Woman?

public class Demo2 {

/**

  • 方法静态分派演示
  • @author zzm

*/

static abstract class Human {

}

 

static class Man extends Human {

}

 

static class Woman extends Human {

}

 

public void sayHello(Human guy) {

System.out.println("hello,guy")?

}

 

public void sayHello(Man guy) {

System.out.println("hello,gentleman")?

}

 

public void sayHello(Woman guy) {

System.out.println("hello,lady")?

}

public static void main(String[] args) {

Human man = new Man()?

Human woman = new Woman()?

Demo2 sr = new Demo2()?

 

sr.sayHello((Man)man)?

sr.sayHello((Woman)woman)?

}

}

结果:

hello,gentlemanhello,lady

注意在这里之和传入的变量有关系的。

重载为什么为什么都是父类的呢?

我们来看一下下面的解释:

我们把上面代码中的"Human"称为变量的静态类型(Static Type),或者叫做的外观类型(Apparent Type),后面的"Man"则称为变量的实际类型(Actual Type),静态类型和

实际类型在程序中都可以发生一些变化,区别是静态类型的变化仅仅在使用时发生,变量本身的静态类型不会被改变,并且最终的静态类型是在编译期可知的;而实际类型变化的结果在运行期才可确定,编译器在编译程序的时候并不知道一个对象的实际类型是什么。重载是编译器就决定了的。

解释了这两个概念,再回到代码清单8-6的样例代码中。main()里面的两次sayHello()方法调用,在方法接收者已经确定是对象"sr"的前提下,使用哪个重载版本,就完全取决于传入参数的数量和数据类型。代码中刻意地定义了两个静态类型相同但实际类型不同的变量,但虚拟机(准确地说是编译器)在重载时是通过参数的静态类型而不是实际类型作为判定依据的。并且静态类型是编译期可知的,因此,在编译阶段,Javac编译器会根据参数的静态类型决定使用哪个重载版本,所以选择了sayHello(Human)作为调用目标,并把这个方法的符号引用写到main()方法里的两条invokevirtual指令的参数中。

所有依赖静态类型来定位方法执行版本的分派动作称为静态分派。静态分派的典型应用是方法重载。静态分派发生在编译阶段,因此确定静态分派的动作实际上不是由虚拟机来执行的。另外,编译器虽然能确定出方法的重载版本,但在很多情况下这个重载版本并不是"唯一的",往往只能确定一个"更加合适的"版本。这种模糊的结论在由0和1构成的计算机世界中算是比较"稀罕"的事情,产生这种模糊结论的主要原因是字面量不需要定义,所以字面量没有显式的静态类型,它的静态类型只能通过语言上的规则去理解和推断。代码清单8-

7演示了何为"更加合适的"版本。

test

标签:invoke   因此   ati   编译器   方法调用   有关   import   test   先来   

原文地址:https://www.cnblogs.com/qingruihappy/p/9658000.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!