Java中的virtual method

今天看jcvm的标准的 时候,看到有一个virtual method,感觉很疑惑,以前看Java的时候并没有发现有这类方法。

百度、Google了一下,才发现,Java中普通方法就是virtual method,动态绑定是Java的默认行为

如果不想让一个方法成为virtual method,只要把这个方法申明为final就可以了。

至于在c++中虚方法是怎么回事,可以参考下面这篇文章

http://www.cnblogs.com/xd502djj/archive/2010/09/22/1832912.html

在很多的博客中也有这样一种说法,Java的virtual method其实就是dynamic binding/dynamic dispatch.

(http://stackoverflow.com/questions/9453701/what-is-virtual-method-calling-in-java)

从这里面的回答可以看出,virtual method就是为了多态而出现的

下面简单的介绍一下动态方法调度。

在Java中,如果一个子类的方法和超类的某个方法具有相同的名称和类型签名,那么称子类中的这个方法重写了超类中相应的方法

当子类中调用被重写的方法时,总是调用由子类定义的版本,由超类定义的版本会被隐藏。

方法重写形成了动态方法调度(dynamic method dispatch)的基础,动态方法调度可以说是Java中最强大的功能

动态方法调度室一种机制,通过这种机制可以在运行时,而不是在编译时解析对重写方法的调用。

动态方法调度就是Java实现多态的机理所在

首先申明一点:超类引用变量可以指向子类对象。Java利用这一事实,在运行时解析对重写方法的调用。

下面是实现原理:

当通过超类引用调用重写的方法时,Java根据在调用时所引用对象的类型来判断调用哪个版本的方法。因此,这个决定是在运行时做出的。

如果引用不同类型的对象,就会调用不同版本的方法。

也就是说,是当前正在引用的对象的类型(而不是引用变量的类型)决定了将要执行哪个版本的重写方法。


例子如下:

public class Test {

  public static void main(String[] args){

    superTest a = new superTest();
    a.eat();

    superTest b = new superTest1();
    b.eat();

    superTest c = new superTest2();
    c.eat();

  }

}

class superTest{

  void eat(){
    System.out.println("this is the superTest print");
  }
}

class superTest1 extends superTest{
  void eat(){
    System.out.println("this is the superTest1 print ");
  }
}

class superTest2 extends superTest{
  void eat(){
    System.out.println("this is the superTest2 print");
  }
}

最后的输出结果是:

this is the superTest print
this is the superTest1 print
this is the superTest2 print

时间: 2024-12-28 21:20:22

Java中的virtual method的相关文章

Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference xxx 的问题分析与解决方案

最近,公司要求开发一个APP,所以很苦逼的学习了几天 Android 的上手手册,但是实际运用于开发中还是捉襟见肘,困难重重:好在的是,部门还有几个专门搞安卓的大佬可以问问,哈哈 好了,进入今天的正题吧,前天开发过程中,遇到一个如“标题”所示的问题,百思不得其解!最终上网搜报错的原因,才找到问题的所在:.xml文件中运用到了不存在的标签--我的是因为粗心把<View>写成了<view>,加载的时候找不到该标签,所以页面一直运行不出来. 所以,该问题基本出在于布局页面有错(有的错误页

java.lang.NullPointerException: Attempt to invoke virtual method &#39;java.util.List com.yunweather.app.db.YunWeatherDB.loadProvinces()&#39; on a null object reference

NullPointerException:查看自己的什么地方是否对空指针进行了操作 Attempt to invoke virtual method 'java.util.List com.yunweather.app.db.YunWeatherDB.loadProvinces()' on a null object reference 尝试用一个空对象引用调用LoadProvinces()方法,查看调用LoadProvinces()的对象是否初始化,很可能是因为你没有初始化就调用了LoadPr

java.lang.NullPointerException: Attempt to invoke virtual method &#39;void 、Handler.removeMessages(int)&#39; on a null object reference

onDestory进行释放Handler时,需要判断null if(null != mHandler) { mHandler.removeMessages(MSG_CHANGE_TEXT_COLOR); mHandler.removeMessages(MSG_JUMP_TO_SUCCESS_PAGE); mHandler.removeMessages(MSG_PLAY_LITTLE_PEOPLE_ANIMATION); mHandler.removeMessages(MSG_PLAY_WRONG

Java中使用HttpRequest调用RESTfull的DELETE方法接口提示:How to fix HTTP method DELETE doesn&#39;t support output

说明:无论是Spring框架还是Spring Boot的Feign形式的客户端,以下的解决方法都适用. 解决方法:直接升级JDK 1.8,这个问题是1.7的BUG. 参考: https://salesforce.stackexchange.com/questions/34624/http-method-delete-doesnt-support-output https://salesforce.stackexchange.com/questions/66097/how-to-fix-http-

c++中继承和java中继承的对比

java中: class Parent{ public void test(int a){ System.out.println("Parent:" + a); System.out.println(this.getClass().getName()); } } class Child extends Parent{ public void test(int a, int b){ System.out.println("Child:" + a + " &q

[转]Java中继承、多态、重载和重写介绍

什么是多态?它的实现机制是什么呢?重载和重写的区别在那里?这就是这一次我们要回顾的四个十分重要的概念:继承.多态.重载和重写. 继承(inheritance) 简单的说,继承就是在一个现有类型的基础上,通过增加新的方法或者重定义已有方法(下面会讲到,这种方式叫重写)的方式,产生一个新的类型.继承是面向对象的三个基本特征--封装.继承.多态的其中之一,我们在使用JAVA时编写的每一个类都是在继承,因为在JAVA语言中,java.lang.Object类是所有类最根本的基类(或者叫父类.超类),如果

java中获取系统属性以及环境变量

java中获取系统属性以及环境变量 System.getEnv()和System.getProperties()的差别 从概念上讲,系统属性 和环境变量 都是名称与值之间的映射.两种机制都能用来将用户定义的信息传递给 Java 进程.环境变量产生很多其它的全局效应,由于它们不仅对Java 子进程可见,并且对于定义它们的进程的全部子进程都是可见的.在不同的操作系统上,它们的语义有细微的区别,比方,不区分大写和小写.由于这些原因,环境变量更可能有意料不到的副作用.最好在可能的地方使用系统属性.环境变

关于 Java 中 finally 语句块的深度辨析

可不能小看这个简单的 finally,看似简单的问题背后,却隐藏了无数的玄机.接下来我就带您一步一步的揭开这个 finally 的神秘面纱. 问题分析 首先来问大家一个问题:finally 语句块一定会执行吗? 很多人都认为 finally 语句块是肯定要执行的,其中也包括一些很有经验的 Java 程序员.可惜并不像大多人所认为的那样,对于这个问题,答案当然是否定的,我们先来看下面这个例子. 清单 1. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1

深刻理解Java中单例模式的实现

在之前的学习笔记中已经写了一篇关于单例模式的几种不同实现.这篇文章主要是对之前的那篇笔记的补充和加深. · 在Java语言中使用单例模式能够带来的好处: (1):对于频繁使用的对象,可以省略创建对象那个所花费的时间,尤其是那些重量级对象的创建,对于重量级对象的创建那可是一笔相当可观的系统开销. (2):由于new操作的次数减少了,进一步产生的益处就是,对系统内存的使用频率也会降低了,那么这一举措将会减轻GC压力,缩短GC停顿时间. 以上的这两点都为系统性能的优化带来了改善. 单例模式的实现: 简