博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Jvm(64),方法调用----解析
阅读量:5835 次
发布时间:2019-06-18

本文共 1708 字,大约阅读时间需要 5 分钟。

假如你现在还在为自己的技术担忧,假如你现在想提升自己的工资,假如你想在职场上获得更多的话语权,假如你想顺利的度过35岁这个魔咒,假如你想体验BAT的工作环境,那么现在请我们一起开启提升技术之旅吧,详情请点击

继续前面关于方法调用的话题,所有方法调用中的目标方法在Class文件里面都是一个常量池中的符号引用,在类加载的解析阶段,会将其中的一部分符号引用转化为直接引用,这种解析能成立的前提是:方法在程序真正运行之前就有一个可确定的调用版本,并且这个方法的调用版本在运行期是不可改变的。换句话说,调用目标在程序代码写好、编译器进行编译时就必须确定下来。这类方法的调用称为解析(Resolution)。

换句话就是说在写好代码之后通过eclipse编译之后,编译出来的结果是不会再变化了。

在Java语言中符合"编译期可知,运行期不可变"这个要求的方法,主要包括静态方法和私有方法两大类,前者与类型直接关联,后者在外部不可被访问,这两种方法各自的特点决定了它们都不可能通过继承或别的方式重写其他版本,因此它们都适合在类加载阶段进行解析

与之相对应的是,在Java虚拟机里面提供了5条方法调用字节码指令,分别如下。

invokestatic:调用静态方法。

invokespecial:调用实例构造器<init>方法、私有方法和父类方法。

invokevirtual:调用所有的虚方法。

invokeinterface:调用接口方法,会在运行时再确定一个实现此接口的对象。

invokedynamic:先在运行时动态解析出调用点限定符所引用的方法,然后再执行该方

法,在此之前的4条调用指令,分派逻辑是固化在Java虚拟机内部的,而invokedynamic指令的分派逻辑是由用户所设定的引导方法决定的。

只要能被invokestatic和invokespecial指令调用的方法,都可以在解析阶段中确定唯一的调用版本,符合这个条件的有静态方法、私有方法、实例构造器、父类方法4类,它们在类加载的时候就会把符号引用解析为该方法的直接引用。这些方法可以称为非虚方法,与之相反,其他方法称为虚方法(除去final方法,后文会提到)。代码清单8-5演示了一个最常见的解析调用的例子,此样例中,静态方sayHello()只可能属于类型StaticResolution,没有任何手段可以覆盖或隐藏这个方法。

我们来看一下案例:

package demo.jvm.test8;

public class Demo1 {

public static void sayHello() {

System.out.println("静态方法的调用");

}

 

public static void main(String[] args) {

sayHello();

}

}

就是在eclipse编译的时候就已经确定了的结果的,不需要等到运行的时候再去确认我运行的是谁的。

Java中的非虚方法除了使用invokestatic、invokespecial调用的方法之外还有一种,就是被final修饰的方法。虽然final方法是使用invokevirtual指令来调用的,但是由于它无法被

覆盖,没有其他版本,所以也无须对方法接收者进行多态选择,又或者说多态选择的结果肯定是唯一的。在Java语言规范中明确说明了final方法是一种非虚方法。解析调用一定是个静态的过程,在编译期间就完全确定,在类装载的解析阶段就会把涉及的

符号引用全部转变为可确定的直接引用,不会延迟到运行期再去完成。而分派

(Dispatch)调用则可能是静态的也可能是动态的,根据分派依据的宗量数[1]可分为单分派和多分派。这两类分派方式的两两组合就构成了静态单分派、静态多分派、动态单分派、动态多分派4种分派组合情况,下面我们再看看虚拟机中的方法分派是如何进行的。

假如你现在还在为自己的技术担忧,假如你现在想提升自己的工资,假如你想在职场上获得更多的话语权,假如你想顺利的度过35岁这个魔咒,假如你想体验BAT的工作环境,那么现在请我们一起开启提升技术之旅吧,详情请点击

转载地址:http://ivucx.baihongyu.com/

你可能感兴趣的文章
第三方支付集成
查看>>
anything vs everything
查看>>
N-gram统计语言模型(总结)
查看>>
SQL - 分页存储过程
查看>>
nginx做负载均衡配置文件
查看>>
xml html entity 列表
查看>>
Selenium Grid 简易安装
查看>>
数据结构——Java实现二叉树
查看>>
前端必须掌握30个CSS3选择器
查看>>
DjangoRestFramework实践笔记
查看>>
谷歌浏览器中安装JsonView扩展程序
查看>>
jsp el 自定义方法 tld 说明
查看>>
Linux查看和剔除当前登录用户
查看>>
QT项视图之QListWidget
查看>>
Chromium Embedded Framework 中文文档(简介)
查看>>
寄生构造函数——扩展原生数组
查看>>
BaseAdapter 注意的关键点!
查看>>
FusionChart实现金字塔分布图
查看>>
斗地主算法的设计与实现–对牌进行排序
查看>>
【转】C++中继承中的同名成员问题
查看>>