java虚拟机规范(se8)——java虚拟机结构(四)
2.7 对象的表示
java虚拟机并不要求对象满足任何特定的内部结构。
在Oracle的一些Java虚拟机实现中,对类实例的引用是指向句柄的指针,该句柄本身是一对指针:一个指向包含对象方法的表和指向表示Class对象的指针对象的类型,另一个是从堆为对象数据分配的内存。
2.8 浮点算法
Java虚拟机包含IEEE二进制浮点运算标准(ANSI / IEEE Std.754-1985,New York)中规定的浮点运算的子集。
2.8.1 Java虚拟机浮点算法和IEEE 754
Java虚拟机支持的浮点运算与IEEE 754标准之间的主要区别是:
- IEEE 754中的定义的无效操作,如被0除,溢出,向下溢出或者不精确,在java虚拟机中不会抛出异常,或者其它IEEE 754中规定的表示方式。java虚拟机没有型号NaN值。(The Java Virtual Machine has no signaling NaN value. )
 - JAVA虚拟机中不支持IEEE 754中的信号浮点比较。(The Java Virtual Machine does not support IEEE 754 signaling floating-point comparisons. )
 - Java虚拟机的舍入操作始终使用IEEE 754舍入到最近模式。不精确的结果四舍五入到最接近的可表示值,并且保证此值的最低有效位为0,这是IEEE 754默认模式。但Java虚拟机指令将浮点类型的值转换为整数类型的值,向零舍入。Java虚拟机没有提供任何改变浮点舍入模式的方法。
 - Java虚拟机不支持IEEE 754单扩展或双扩展格式,但是在双精度浮点数集合和双精度扩展指数集合范围与单精度扩展指数格式的表示会有重叠。单精度扩展指数和双精度扩展指数值集(可选择支持)与IEEE 754扩展格式的值不对应:IEEE 754扩展格式规定了扩展精度以及扩展指数范围。
 
2.8.2 浮点格式
每一个方法都有一个浮点模式,要么是FP-strict,要么时not FP-strict。方法的浮点格式由方法的method_info结构中access_flags项的ACC_STRICT标志来决定。如果设置了这个标志位就是FP-strict,否则就是not FP-strict。
请注意,ACC_STRICT标志的这种映射意味着由JDK 1.1版或更早版本中的编译器编译的类中的方法实际上时not FP-strict。
当调用创建包含操作数堆栈的帧的方法具有浮点模式时,我们将操作数堆栈称为具有给定的浮点模式。类似地,当包含该指令的方法具有该浮点模式时,我们将该Java虚拟机指令称为具有给定的浮点模式。
如果支持单精度扩展指数集(第2.3.2节),则非FP-strict的操作数堆栈上float类型的值可以超出该值集,除非值集转换禁止(§2.8.3))。如果支持双精度扩展指数集(第2.3.2节),则非FP-strict的操作数堆栈上的double类型值可以超出该值集,除非值集转换禁止。
在所有其他上下文中,无论是在操作数堆栈上还是在其他位置上,无论浮点模式如何,float和double类型的浮点值只能分别在单精度浮点集和双精度浮点集的范围内。特别是,类和实例字段、数组元素、局部变量和方法参数只能从标准值集中取值。
2.8.3 数值集转换
在一些特定场景下,支持扩展指数集合的 Java 虚拟机实现数值在标准浮点数集合与扩展指数集合之间的映射关系是允许和必要的,这种映射操作就称为数值集合转换数值集合转换并非数据类型转换,而是在同一种数据类型之中不同数值集合的映射操作。
在指示值集转换的情况下,允许实现对值执行以下操作之一:
- 如果一个值的类型为float,并且不是float值集的元素,则它将值映射到float值集的最近元素。
 - 如果值的类型为double且不是double值集的元素,则它将值映射到double值集的最近元素。
 
另外,如果如果要进行数值集转换,则需要执行下面的操作:
- 假设非FP-strict的Java虚拟机指令执行时导致了float类型的值被推送到FP-strict的操作数堆栈,如作为参数传递,或存储到局部变量,字段或数组的元素。如果该值不是floa值集的元素,则将该值映射到float值集的最近元素。
 - 假设非FP-strict的Java虚拟机指令执行时导致了double类型的值被推送到FP-strict的操作数堆栈,如作为参数传递,或存储到局部变量,字段或数组的元素。如果该值不是double值集的元素,则将该值映射到double值集的最近元素。
 
在方法调用期间传递浮点类型的参数(包括本地方法调用)可能会发生这种所需的值集转换,如:将浮点类型的值从非FP-strict的方法返回到FP-strict的方法、或者将浮点类型的值存储到非FP严格的方法中的局部变量,字段或数组中。
并非扩展指数值集中的所有值都可以精确映射到相应标准值集中的值。如果映射的值太大而无法准确表示(其指数大于标准值集允许的值),则将其转换为相应类型的(正或负)无穷大。如果映射的值太小而不能精确表示(其指数小于标准值集所允许的值),则将其舍入到最接近的可表示的非规范化值或相同符号的零。
数值集转换不会转换无限大、无限小和NaN并且不会改变值的符号。
2.9 特殊方法
从java虚拟机的维度来看,每一个使用java编程语言编写的构造器都是一个实例初始化方法(instance initialization method),并且有一个特殊的名字<init>。这个名称有编译器提供,因为<init>在java编程语言中不是一个合法的标识符,无法使用java编程语言编写。实例初始化方法只能被java虚拟机通过指令调用,并且只会被调用在未初始化的实例上。实例初始化方法和构造器的访问权限一致。
一个类或者接口最多只有一个类或接口初始化方法(class or interface initialization method),通过调用这个初始化方法来初始化这个类或者接口。类或者接口的初始化方法有一个特殊的名称<clinit>,它没有参数,并且返回值为void。
类文件中名为<clinit>的其他方法无关紧要。 它们不是类或接口初始化方法。 它们不能被任何Java虚拟机指令调用,并且永远不会被Java虚拟机本身调用。
在版本号为51.0或以上的类文件中,方法必须另外设置ACC_STATIC标志(§4.6),以便成为类或接口初始化方法。
这个需求是在Java SE 7中引入的。在版本号为50.0或更低的类文件中,一个名为<clinit>的方法返回值是void的,不接受任何参数,不管它的ACC_STATIC标志设置如何,都被认为是类或接口初始化方法。
<clinit>名称由编译器提供,因为这不是一个有效的标识符,它不能在java编程语言直接使用。类和接口的初始化方法被java虚拟机隐式调用,它们从来不会被java虚拟机指令直接调用,而是作为类初始化过程中一部分被间接调用。
如果下列条件都为真,则方法为签名多态(signature polymorphic):
- 它在java.lang.invoke.MethodHandle类中声明
 - 它只有一个Object[] 参数
 - 它的返回类型是Object
 -   它的设置了
ACC_VARARGS和ACC_NATIVE标志位 
  在Java SE 8中,仅有的签名多态方法( signature polymorphic)是java.lang.invoke.MethodHandle类中的invoke 和 invokeExact方法。
Java虚拟机在invokevirtual指令中对签名多态方法进行了特殊处理,以实现方法句柄(method handle)的调用。方法句柄是对底层方法、构造函数、字段或类似低级操作(§5.4.3.5)的强类型,直接可执行的引用,具有可选的参数或返回值转换。这些转换非常普遍,包括转换、插入、删除和替换等模式。可以从Java SE平台API中的java.lang.invoke包中获取更多信息。
java虚拟机规范(se8)——java虚拟机结构(四)的更多相关文章
- java虚拟机规范(se8)——java虚拟机结构(一)
		
本文翻译自:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html 第二章 虚拟机结构 本文档描述了一个抽象的虚拟机规范,并不描述 ...
 - java虚拟机规范(se8)——java虚拟机的编译(四)
		
3.12 抛出和处理异常 在程序中使用throw关键字来抛出异常.编译结果很简单. void cantBeZero(int i) throws TestExc { if (i == 0) { thro ...
 - java虚拟机规范(se8)——java虚拟机结构(二)
		
2.5 运行时数据区域 java虚拟机定义了多个用于程序执行期间的运行时数据区域.这些数据区域中一些随着java虚拟机的启动而创建,随着虚拟机的退出而销毁.其他的数据区域时和线程相关的.线程相关数据区 ...
 - java虚拟机规范(se8)——java虚拟机结构(六)
		
2.11 指令集简介 java虚拟机指令由一个字节的操作码,接着时0个或多个操作数组成,操作码描述了执行的操作,操作数提供了操作所需的参数或者数据.许多指令没有操作数只包含一个操作码. 如果忽略异常处 ...
 - java虚拟机规范(se8)——java虚拟机的编译(一)
		
本文翻译自:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html 第三章 java虚拟机的编译 java虚拟机是设计用来支持ja ...
 - java虚拟机规范(se8)——java虚拟机结构(三)
		
2.6. 栈帧 栈帧用于存储数据和部分结果,同样也用于执行动态链接,返回方法的值和分派异常. 当方法被调用的时候会创建一个新的栈帧.当一个方法调用结束时,它对应的栈帧就被销毁了,不管是正常调用结束还是 ...
 - java虚拟机规范(se8)——java虚拟机结构(五)
		
2.10 异常 java虚拟机中的异常用Throwable类或者它的子类的实例来表示.抛出一个异常会导致立即非本地(an inmediate nolocal)的控制转移,从发生异常的地方跳到处理异常的 ...
 - java虚拟机规范(se8)——java虚拟机的编译(三)
		
3.6 接受参数 如果n个参数传给一个实例的方法,按照约定,它们被接受并放在这个新方法创建的栈帧中的局部变量表里,在局部变量表中的序号从1到n.这些参数按照它们传递过来的顺序存放.例如: int ad ...
 - java虚拟机规范(se8)——java虚拟机的编译(二)
		
3.3 算术运算 java虚拟机通常在操作数栈上进行算术运算(例外情况是iinc指令,它直接增加一个局部变量的值).例如下面的align2grain()方法,它的作用是将int值对齐到2的指定次幂: ...
 
随机推荐
- code review & github
			
code review & github code review https://github.com/features/code-review/ https://github.com/mar ...
 - Chrome Ajax 跨域设置
			
一.前言 web 开发中 Ajax 是十分常见的技术,但是在前后端使用接口对接的调试过程中不可避免会碰到跨域问题.今天我给大家介绍一个十分简单有效的方法. 跨域经典错误 二.Chrome 跨域设置 首 ...
 - 两种常用文件分享方式 - 网络硬盘快速分享, 点对点的文件共享 BitTorrent Sync
			
普通的用户经常通过电子邮件.QQ传递等方式进行文件的分享,但是由于不同的网络环境有的时候可能会有不同的限制,所以我们就需要寻找其他的方式来替代.今天就为大家推荐两个既常用又与众不同的分享方式. 中国论 ...
 - 牛客网暑期ACM多校训练营(第二场)J	farm (二维树状数组)
			
题目链接: https://www.nowcoder.com/acm/contest/140/J 思路: 都写在代码注释里了,非常好懂.. for_each函数可以去看一下,遍历起vector数组比较 ...
 - 【刷题】洛谷 P4320 道路相遇
			
题目描述 在 H 国的小 w 决定到从城市 \(u\) 到城市 \(v\) 旅行,但是此时小 c 由于各种原因不在城市 \(u\),但是小 c 决定到在中途与小 w 相遇 由于 H 国道路的原因,小 ...
 - SDOI2017 R2泛做
			
由于各种原因,在bzoj上我day1的题一题都没过,所以这里就直接贴loj的链接好了. D1T1 龙与地下城 中心极限定理. https://en.wikipedia.org/wiki/Central ...
 - mysql主主同步设置
			
mysql主主同步设置 主主同步设置是同等的地位,所以以下操作在两台机器上都需要进行而且操作是相同的. 服务器 服务器代号 IP hostname A 192.168.70.128 Debian1 B ...
 - VUE.JS 窗口发生变化时,获取当前窗口的高度。
			
VUE.JS # 窗口发生变化时,获取当前窗口的高度. mounted () { const that = this; window.onresize = () => { return (() ...
 - Excel:公式应用技巧汇总
			
1.合并单元格添加序号:=MAX(A$1:A1)+1 不重复的个数: 公式1:{=SUM(1/COUNTIF(A2:A8,A2:A8))} 公式2:{=SUM(--(MATCH(A2:A8,A2:A8 ...
 - CXF wsdl2java 生成java代码供客户端使用
			
CXF wsdl2java 生成java代码供客户端使用 环境配置:1.下载apache-cxf-2.6.2在环境变量中配置CXF_HOME 值为E:\gavin\cxf\apache-cxf-3.0 ...