- 浏览: 3015232 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (430)
- Programming Languages (23)
- Compiler (20)
- Virtual Machine (57)
- Garbage Collection (4)
- HotSpot VM (26)
- Mono (2)
- SSCLI Rotor (1)
- Harmony (0)
- DLR (19)
- Ruby (28)
- C# (38)
- F# (3)
- Haskell (0)
- Scheme (1)
- Regular Expression (5)
- Python (4)
- ECMAScript (2)
- JavaScript (18)
- ActionScript (7)
- Squirrel (2)
- C (6)
- C++ (10)
- D (2)
- .NET (13)
- Java (86)
- Scala (1)
- Groovy (3)
- Optimization (6)
- Data Structure and Algorithm (3)
- Books (4)
- WPF (1)
- Game Engines (7)
- 吉里吉里 (12)
- UML (1)
- Reverse Engineering (11)
- NSIS (4)
- Utilities (3)
- Design Patterns (1)
- Visual Studio (9)
- Windows 7 (3)
- x86 Assembler (1)
- Android (2)
- School Assignment / Test (6)
- Anti-virus (1)
- REST (1)
- Profiling (1)
- misc (39)
- NetOA (12)
- rant (6)
- anime (5)
- Links (12)
- CLR (7)
- GC (1)
- OpenJDK (2)
- JVM (4)
- KVM (0)
- Rhino (1)
- LINQ (2)
- JScript (0)
- Nashorn (0)
- Dalvik (1)
- DTrace (0)
- LLVM (0)
- MSIL (0)
最新评论
-
mldxs:
虽然很多还是看不懂,写的很好!
虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩 -
HanyuKing:
Java的多维数组 -
funnyone:
Java 8的default method与method resolution -
ljs_nogard:
Xamarin workbook - .Net Core 中不 ...
LINQ的恶搞…… -
txm119161336:
allocatestlye1 顺序为 // Fields o ...
最近做的两次Java/JVM分享的概要
继续打捞站内信。
Java和JVM里本来就没有所谓的“矩形数组”的概念,多维数组只有“数组的数组”(array-of-arrays)或者叫jagged array。
与之对比,C#和CLI里就有真正的多维“矩形”数组,也支持“数组的数组”。关于几种不同的语言里多维数组的差异,可以参考以前一帖。
也就是说,在Java里
一个数组类型的“组件类型”(component type)就是该数组类型的维度(dimension)减去1的类型;字面上看也就是少一对[]。
每个维度上都是一个真正的数组对象。每个数组对象都记录着自己的长度(length)。所以对每个数组对象都可以用arraylength指令去查询它们的长度,每个Xaload / Xastore也就可以做相应的边界检查。
这只是个简写而已。虽然这个语句的右手边对应与一组JVM字节码指令,
实际上它的作用大致等同于:
以32位HotSpot VM的实现为例,上面两个版本的代码创建出来的对象都是这种样子的:
这样就好理解了吧?
可以参考JVM规范去了解multianewarray的语义:
http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc9.html#multianewarray
HotSpot VM的实现里,参考解释器版的实现比较直观,在这里:
interpreterRuntime.cpp: InterpreterRuntime::multianewarray
objArrayKlass.cpp: objArrayKlass::multi_allocate
typeArrayKlass.cpp: typeArrayKlass::multi_allocate
该指令接受两个参数,
第一个是多维数组的类型,这个例子是里[[[I,也就是int[][][];
第二个是多维数组的维度n,这个例子里n=3。
知道了维度之后,JVM执行这条指令时就会从操作数栈顶弹出n个值(必须都是int型),并以这些int为每个维度的length嵌套循环的去创建数组对象出来;这个例子里也就是把前面iconst_2、iconst_3、iconst_4指令压到操作数栈上的常量2、3、4分别弹出来,并且作为数组的各维度的长度去创建实例。
multianewarray与上面写的那种显式用嵌套循环来初始化多维数组的Java代码最大的差异是,multianewarray会检查所有维度上的length是否非负,如果有负数就会抛NegativeArraySizeException;要注意的是无论传入的多维数组是否有维度的长度是0,所有维度都会被检查。
而显然,如果显式用嵌套循环来初始化的话,负数长度的问题就有可能“逃过去”。
看例子:
这个会抛NegativeArraySizeException异常:
而
这个不会抛异常。
嗯…“组件类型”听起来怪怪的,不过就先用它吧 ^^
嗯完全正确。多谢补充
这2个指令也会抛出NegativeArraySizeException,只不过这个异常并非Linking Exception,换句话说,代码不执行到它就没有问题。
所以请同学们看清楚,撒迦使用的是:
同学F 写道
在java中的数组访问,举个例子,对于数组int[][][] arry = new int[2][3][4],我从字节码上看,虚拟机对某个arry中的某个元素如arry[1][1][3]的访问,似乎是先获取arry[1]的引用,然后再获取arry[1][1]的引用,再获取数据arry[1][1][3],如果这个过程我没有理解错的话,那么虚拟机是不是对这些“中间引用”(arry[1]、arry[1][1]之类的)创建相应的类型,否则单凭这些引用如何进行数组下表的越界校验?
Java和JVM里本来就没有所谓的“矩形数组”的概念,多维数组只有“数组的数组”(array-of-arrays)或者叫jagged array。
与之对比,C#和CLI里就有真正的多维“矩形”数组,也支持“数组的数组”。关于几种不同的语言里多维数组的差异,可以参考以前一帖。
也就是说,在Java里
类型 | 说明 |
int | 这是一个基本类型 |
int[] | 这是以int为元素的数组类型 |
int[][] | 这是以int[]为元素的数组类型 |
int[][][] | 这是以int[][]为元素的数组类型 |
一个数组类型的“组件类型”(component type)就是该数组类型的维度(dimension)减去1的类型;字面上看也就是少一对[]。
每个维度上都是一个真正的数组对象。每个数组对象都记录着自己的长度(length)。所以对每个数组对象都可以用arraylength指令去查询它们的长度,每个Xaload / Xastore也就可以做相应的边界检查。
int[][][] array = new int[2][3][4];
这只是个简写而已。虽然这个语句的右手边对应与一组JVM字节码指令,
0: iconst_2 1: iconst_3 2: iconst_4 3: multianewarray #2, 3; //class "[[[I"
实际上它的作用大致等同于:
int[][][] a = new int[2][][]; for (int i = 0; i < a.length; i++) { a[i] = new int[3][]; for (int j = 0; j < a[i].length; j++) { a[i][j] = new int[4]; } }
以32位HotSpot VM的实现为例,上面两个版本的代码创建出来的对象都是这种样子的:
这样就好理解了吧?
可以参考JVM规范去了解multianewarray的语义:
http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc9.html#multianewarray
HotSpot VM的实现里,参考解释器版的实现比较直观,在这里:
interpreterRuntime.cpp: InterpreterRuntime::multianewarray
objArrayKlass.cpp: objArrayKlass::multi_allocate
typeArrayKlass.cpp: typeArrayKlass::multi_allocate
该指令接受两个参数,
第一个是多维数组的类型,这个例子是里[[[I,也就是int[][][];
第二个是多维数组的维度n,这个例子里n=3。
知道了维度之后,JVM执行这条指令时就会从操作数栈顶弹出n个值(必须都是int型),并以这些int为每个维度的length嵌套循环的去创建数组对象出来;这个例子里也就是把前面iconst_2、iconst_3、iconst_4指令压到操作数栈上的常量2、3、4分别弹出来,并且作为数组的各维度的长度去创建实例。
multianewarray与上面写的那种显式用嵌套循环来初始化多维数组的Java代码最大的差异是,multianewarray会检查所有维度上的length是否非负,如果有负数就会抛NegativeArraySizeException;要注意的是无论传入的多维数组是否有维度的长度是0,所有维度都会被检查。
而显然,如果显式用嵌套循环来初始化的话,负数长度的问题就有可能“逃过去”。
看例子:
public class Foo { public static void main(String[] args) { int[][][] array = new int[1][0][-1]; } }
这个会抛NegativeArraySizeException异常:
$ java Foo Exception in thread "main" java.lang.NegativeArraySizeException at Foo.main(Foo.java:3)
而
public class Bar { public static void main(String[] args) { int[][][] a = new int[1][][]; for (int i = 0; i < a.length; i++) { a[i] = new int[0][]; for (int j = 0; j < a[i].length; j++) { // a[i].length == 0 a[i][j] = new int[-1]; // 这个循环体不会被执行,-1的长度就被“跳过去”了 } } } }
这个不会抛异常。
评论
5 楼
HanyuKing
2019-01-29
4 楼
RednaxelaFX
2011-05-31
IcyFenix 写道
讨论一下文中一个字面翻译的问题:
component type是否翻译成“组件类型”会恰当一些?因为数组里面还有个element type表示“所有[]都去掉”的那个类型,把“元素类型”留给它会不会好一些?
RednaxelaFX 写道
一个数组类型的“元素类型”(component type)就是该数组类型的维度(dimension)减去1的类型;字面上看也就是少一对[]。
component type是否翻译成“组件类型”会恰当一些?因为数组里面还有个element type表示“所有[]都去掉”的那个类型,把“元素类型”留给它会不会好一些?
JVMS 3,chapter 2.4 写道
An array type consists of a component type with a single dimension (whose length is not given by the type). The component type of an array type may itself be an array type. If, starting from any array type, one considers its component type, and then (if that is also an array type) the component type of that type, and so on, eventually one must reach a component type that is not an array type; this is called the element type of the array type
嗯…“组件类型”听起来怪怪的,不过就先用它吧 ^^
3 楼
IcyFenix
2011-05-31
讨论一下文中一个字面翻译的问题:
component type是否翻译成“组件类型”会恰当一些?因为数组里面还有个element type表示“所有[]都去掉”的那个类型,把“元素类型”留给它会不会好一些?
RednaxelaFX 写道
一个数组类型的“元素类型”(component type)就是该数组类型的维度(dimension)减去1的类型;字面上看也就是少一对[]。
component type是否翻译成“组件类型”会恰当一些?因为数组里面还有个element type表示“所有[]都去掉”的那个类型,把“元素类型”留给它会不会好一些?
JVMS 3,chapter 2.4 写道
An array type consists of a component type with a single dimension (whose length is not given by the type). The component type of an array type may itself be an array type. If, starting from any array type, one considers its component type, and then (if that is also an array type) the component type of that type, and so on, eventually one must reach a component type that is not an array type; this is called the element type of the array type
2 楼
RednaxelaFX
2011-05-19
IcyFenix 写道
这个例子小小滴补充一下,避免有同学误以为multianewarray指令会抛NegativeArraySizeException,而使用anewarray和newarray组合就不会抛NegativeArraySizeException。
嗯完全正确。多谢补充
1 楼
IcyFenix
2011-05-19
public class Bar { public static void main(String[] args) { int[][][] a = new int[1][][]; for (int i = 0; i < a.length; i++) { a[i] = new int[0][]; for (int j = 0; j < a[i].length; j++) { a[i][j] = new int[-1]; } } } }这个例子小小滴补充一下,避免有同学误以为multianewarray指令会抛NegativeArraySizeException,而使用anewarray和newarray组合就不会抛NegativeArraySizeException。
这2个指令也会抛出NegativeArraySizeException,只不过这个异常并非Linking Exception,换句话说,代码不执行到它就没有问题。
所以请同学们看清楚,撒迦使用的是:
int[][][] array = new int[1][0][-1];而不是
int[][][] array = new int[1][1][-1];或者
int[][][] array = new int[1][-1][-1];后面2条用anewarray和newarray来写也会抛异常。
发表评论
-
The Prehistory of Java, HotSpot and Train
2014-06-02 08:18 0http://cs.gmu.edu/cne/itcore/vi ... -
MSJVM and Sun 1.0.x/1.1.x
2014-05-20 18:50 0当年的survey paper: http://www.sym ... -
Sun JDK1.4.2_28有TieredCompilation
2014-05-12 08:48 0原来以前Sun的JDK 1.4.2 update 28就已经有 ... -
IBM JVM notes (2014 ver)
2014-05-11 07:16 0Sovereign JIT http://publib.bou ... -
class data sharing by Apple
2014-03-28 05:17 0class data sharing is implement ... -
Java 8与静态工具类
2014-03-19 08:43 16134以前要在Java里实现所谓“静态工具类”(static uti ... -
Java 8的default method与method resolution
2014-03-19 02:23 10327先看看下面这个代码例子, interface IFoo { ... -
HotSpot Server VM与Server Class Machine
2014-02-18 13:21 0HotSpot VM历来有Client VM与Server V ... -
Java 8的lambda表达式在OpenJDK8中的实现
2014-02-04 12:08 0三月份JDK8就要发布首发了,现在JDK8 release c ... -
GC stack map与deopt stack map的异同
2014-01-08 09:56 0两者之间不并存在包含关系。它们有交集,但也各自有特别的地方。 ... -
HotSpot Server Compiler与data-flow analysis
2014-01-07 17:41 0http://en.wikipedia.org/wiki/Da ... -
基于LLVM实现VM的JIT的一些痛点
2014-01-07 17:25 0同事Philip Reames Sanjoy Das http ... -
tailcall notes
2013-12-27 07:42 0http://blogs.msdn.com/b/clrcode ... -
《自制编程语言》的一些笔记
2013-11-24 00:20 0http://kmaebashi.com/programmer ... -
字符串的一般封装方式的内存布局 (1): 元数据与字符串内容,整体还是分离?
2013-11-07 17:44 22248(Disclaimer:未经许可请 ... -
字符串的一般封装方式的内存布局 (0): 拿在手上的是什么
2013-11-04 18:22 21365(Disclaimer:未经许可请 ... -
字符串的一般封装方式的内存布局
2013-11-01 12:55 0(Disclaimer:未经许可请 ... -
关于string,内存布局,C++ std::string,CoW
2013-10-30 20:45 0(Disclaimer:未经许可请 ... -
对C语义的for循环的基本代码生成模式
2013-10-19 23:12 21735之前有同学在做龙书(第二版)题目,做到8.4的练习,跟我对答案 ... -
Java的instanceof是如何实现的
2013-09-22 16:57 0Java语言规范,Java SE 7版 http://docs ...
相关推荐
详解java多维数组,提高对java多维数组的理解
题目: 假定本学期某班上有5门课,该班上有10人 (1) 请输入该班同学的学号,姓名,5门课的成绩至数组A、B中,再按5门课的总分排序,然后列出排序后的序号,学号,姓名,成绩1~5; (2) 求出5门课的平均成绩
java多维数组.txt
java100例之实例3 演示一维数组和多维数组的初始化和基本操作.rar
主要介绍了Java多维数组和Arrays类方法总结详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
可以用来简单学习的代码,也是自己学习过程中的一个记录
Java语言编程 多维数组 Java语言编程 多维数组
前端HTML5+CSS3+JS+AJAX零基础入门到项目实战视频教程
使用java语言,对二维数组进行倒置操作
Java中多维数组.pdf 学习资料 复习资料 教学资源
对java中数组的概念、使用、内存的使用情况都有详细说明。包括了一维、二维、多维数组
Java中使用数组完成学生成绩统计的多种实现代码清单.pdf 学习资料 复习资料 教学资源
控制台实现显示二维动态数组的图形,变形,编辑,表示。
Matlab的多维数组操作
Java数组相关资料,部分题目。有兴趣的同学可以了解一下
Learn_core_java_day_13 ...第13天:多维数组 第14天:ArrayList和集合 第15天-排序和搜索 第16天:例外 第17天:文件输入/输出 第18天:使用Java Swing进行GUI编程 第19天:接口和继承。 第20天:Web服务
在多维数组怎么去除重复的数据详细视频教学
1、资源内容:Matlab多维数组漫谈教程(源码).rar 2、代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 3、适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业...
多维数组中怎么判断每一个数出现的次数详细视频教程
Java的数组是一种常用的数据结构,用于存储和操作一组相同类型的元素。...此外,我们还会探讨多维数组的概念和遍历方法。通过学习本文,您将深入了解Java数组的基本概念和常用操作,能够灵活运用数组解决实际问题。