首页 > 编程语言 >java中关于继承,多态及方法调用的底层细节

java中关于继承,多态及方法调用的底层细节

时间:2023-01-13 11:35:11浏览次数:44  
标签:调用 java Man 多态 Human 类型 父类 方法 底层

java中关于继承,多态及方法调用的底层细节

一、继承

继承已存在的类就是复用(继承)这些类的方法和域。在此基础上,还可以添加一些新的方法和域, 以满足新的需求。

子类会拥有父类的全部域和方法(但是受限于访问权限,未必访问得到),在此基础上可以:添加域和方法,覆盖父类方法

访问权限:

protected关键字

子类可访问

一个典型的例子是Object.clone()方法

Object的子类内部是可以调用该方法,也可以重写该方法,如果子类没有显式重写clone方法,是无法调用子类的clone方法的

因为我们的代码和Object类不在同一个包里,访问不到该方法,然而子类是可以访问到的。

super关键字:

  1. super()访问父类的构造函数,进行一些初始化工作,必须放在构造函数第一句。不写的话默认执行父类的无参构造

  2. super.xxx访问父类的成员。注意,方法重写不代表父类方法没了

强制类型转换:

改变一个对象的引用类型,

向上转完全没问题,向下转要看这个对象的实际类型

二、多态及方法调用细节

首先要强调几个注意点:

Human h=new Man()这里的Human被称为静态类型,Man被称为实际类型

1.编译期无法确定一个对象的实际类型,只能知道它的静态类型

2.编译期结束得到的是符号引用,对于方法来说,得到的是方法签名,但是由于继承层次中可能存在方法签名相同的方法,故编译期结束,部分方法并不能确定到底调用哪一个。

3.方法调用是要确定调用哪一个方法

1. 静态绑定:

在类加载的解析(resolution)阶段,JVM会将符号引用转变为直接引用,结合上述第二点,我们给出在解析阶段可以确定直接引用的方法类型:

  • 静态方法:直接由类确定
  • 私有方法:外部不可访问
  • 构造器
  • 父类方法
  • final方法

我们不难看出,这些方法都满足编译器可知,运行期不可变的条件,即在编译期结束即可确定,不存在方法签名或者说符号引用的不确定性。我们将之称为静态绑定。

2. 动态绑定:

除上述方法外,其余方法无法在解析阶段确定直接引用,这些方法被称为虚方法,在JVM中通过invokevirtual指令调用执行

invokevirtual指令运行过程:

  • 找到操作数栈顶的第一个元素(要执行的方法的接收者,所有者)指向的实例对象的实际类型C(即代码中h的实际类型Man)
  • 在类型C里找和符号引用相符的方法,检查访问权限,通过则返回该方法的直接引用
  • 没有则到C的父类里找
class Human{
    public void eat(){}
}
class Man{
    public void eat(){}
    public void eat(int n){}
}

public static void main(){
    Human h=new Man();
    h.eat();
}

3. 编译期的静态分派

上述动态绑定的过程其实就是方法重写的底层实现,接下来看一看方法的重载。

重载过程是在编译期实现的,主要目的是为了确定要调用的方法的方法签名。

仍以上述代码为例,在编译h.eat();时,编译器会做如下几件事:

  • 查看h的静态类型和方法名,列出h的静态类型,也就是Human类,及其父类的的全部同名方法
  • 查看调用方法时提供的参数的静态类型,这里没有参数。在上面列出的方法中寻找与之匹配的,(这里参数类型允许向上转)

即:

class Example{
    public void ex(Human h);
}

public static void main(){
    Example e=new Example();
    e.ex(new Man());
}
// 若Example类的父类中没有ex(Man m)这样的方法,就会匹配到ex(Human h)方法。

至此编译器便得到了要调用方法的方法名和参数类型,也就是所谓的方法签名。

三、参考资料

  1. 《java核心技术卷Ⅰ》
  2. 《深入理解java虚拟机——JVM高级特性与最佳实践》第三版

鄙人只是一名在读的软件工程专业的本科生,正在复习找工作,故而将复习时遇到的一些有意思的东西总结出来,既是加深理解,也是便于日后复习。

鄙人才疏学浅,若文中有谬误之处,还望诸位不吝斧正,以免误人子弟。若有同道中人想一同讨论学习,也可以联系我=>[email protected]。未经作者允许,请勿转载!

路漫漫其修远兮,吾将上下而求索。

标签:调用,java,Man,多态,Human,类型,父类,方法,底层
From: https://www.cnblogs.com/legolas-PRC/p/17049080.html

相关文章

  • java数据类型
    Java语言支持的数据类型分为两种:基本数据类型(PrimitiveType)和引用数据类型(ReferenceType)Java基本数据类型基本数据类型包括Boolean(布尔值)、flot(单精度浮点型)、char(字......
  • 如何通过Java应用程序将Word转为Excel
    平时在工作中,很多小伙伴会习惯性地将文件保存为Word文档格式,但有时会发现某些文件如果保存成Excel表格可能会更好地呈现。例如有的文本在Word文本中不如在Excel工作表编辑计......
  • kettle java 代码调用
    使用程序调用kettlepom.xml点击查看代码<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.or......
  • JavaScript 并发模型
    JavaScript并发模型JavaScript是一种单线程语言,这意味着它只有一个执行线程。这意味着,当JavaScript代码正在运行时,它会阻塞其他所有代码的执行。这种模型称为单线程模型......
  • JAVA中DNS缓存设置(转)
    原文:https://blog.csdn.net/guanfengliang1988/article/details/92813431作者:夜风_BLOG我们上网的原点就是打开浏览器,在上方地址栏输入网址的那一刻,这个回车按了之后,发生......
  • 来自StateOfJS调查:2022年JavaScript生态圈趋势报告(前端早读课)
    原文我这里记录些觉得有趣的。Promise.allSettled()完成所有输入的方法,nomatterwhat,返回对应的状态和值/原因,这对想知道所有返回状态的业务很好用;使用async/await没法......
  • JavaDoc
    JavaDocjavadoc命令是用来生成自己API文档的参数信息@author作者名@version版本号@since指明需要最早使用的jdk版本@param参数名@return返回值情况@thro......
  • Java基础——异常处理
    异常概述所谓“程序”,就是按照次序,一步一步执行的指令;那么“异常”,就是程序没有按我们期待的次序执行时,程序给出的提示。在JAVA语言中,通过定义不同的异常类型,来提示不同......
  • JavaScript表单form
    form表单实例1<!DOCTYPEhtml>2<html>3<head>4<metacharset="utf-8">5<title>javascriptform表单</title>6</head>7......
  • 【转】用“逐步排除”的方法定位Java服务线上“系统性”故障
    一、摘要由于硬件问题、系统资源紧缺或者程序本身的BUG,Java服务在线上不可避免地会出现一些“系统性”故障,比如:服务性能明显下降、部分(或所有)接口超时或卡死等。其中部分......