`
wzucxd
  • 浏览: 25201 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

j2se 数组的创建

 
阅读更多

The JavaTM Virtual Machine Specification Second Edition
5.3.3 Creating Array Classes
The following steps are used to create the array class C denoted by N using class loader L. Class loader L may be either the bootstrap class loader or a user-defined class loader.
If L has already been recorded as an initiating loader of an array class with the same component type as N, that class is C, and no array class creation is necessary. Otherwise, the following steps are performed to create C:

If the component type is a reference type, the algorithm of this section (§5.3) is applied recursively using class loader L in order to load and thereby create the component type of C.

The Java virtual machine creates a new array class with the indicated component type and number of dimensions. If the component type is a reference type, C is marked as having been defined by the defining class loader of the component type. Otherwise, C is marked as having been defined by the bootstrap class loader. In any case, the Java virtual machine then records that L is an initiating loader for C (§5.3.4). If the component type is a reference type, the accessibility of the array class is determined by the accessibility of its component type. Otherwise, the accessibility of the array class is public.
http://java.sun.com/docs/books/jvms/second_edition/html/ConstantPool.doc.html#79473

1.类加载器检查数组类是否已经创建了。没有,则需要创建数组类。否则,就无需创建了。
2.如果数组元素是引用类型,那么类加载器会先加载数组类。
3.JVM根据元素类型和维度,创建相应的数组类。 (解释:数组类由维度和定义类型所决定,即维度不同类型相同则不属于同一个类,维度相同类型相同(即使长度不一样)才是同一个类,(注意:长度不是这个类的成员变量,虽然看上去很像,我们可以通过反射的机制检查下))

1.为什么获取数组的长度用.length(成员变量的形式),而获取String的长度用.length()(成员方法的形式) class loader加载完数组类后,都是调用 arraylength,对于String本身是一个新的不同于数组类的对象,暴露的length()方式也是arraylength的调用
2.数组对象的类是什么? 不是java.util.Arrays,首先需要明确和这个没有关系 数组类由维度和定义类型所决定,即维度不同类型相同则不属于同一个类,维度相同类型相同(即使长度不一样)才是同一个类,(注意:长度不是这个类的成员变量,虽然看上去很像,通过反射的机制检查下)....这个类是一个非法命名类,估计是为了避免和其他自定义类产生冲突,java.lang.Class 550行中有描述
3.JVM没有为数组类生成length这个成员变量,那么Array.length这样的语法如何通过编译执行的?需要阅读字节码

int[] xxx = new int[1];
Class extends int[]> clazz = xxx.getClass();
//class [I 没有任何package的非法类名
//数组的类名由若干个'['和数组元素类型的内部名称组成,'['的数目 代表了数组的维度
System.out.println(xxx.getClass().getName());
System.out.println(clazz.getDeclaredFields().length);
System.out.println(clazz.getDeclaredMethods().length);
System.out.println(clazz.getDeclaredConstructors().length);
System.out.println(clazz.getDeclaredAnnotations().length);
System.out.println(clazz.getDeclaredClasses().length);
System.out.println(clazz.getSuperclass());

[I
0
0
0
0
0
class java.lang.Object

public class Test {
public static void main(String[] args) {
int ab[] = new int[3]; int ii = ab.length;
}
}

public static void main(java.lang.String[]);
Code:
Stack=1, Locals=3, Args_size=1
0: iconst_3 //将int型常量3压入操作数栈
1: newarray int //常量3出栈,初始化维度为1个int数值,引用压栈
3: astore_1 //引用出栈,保存索引到1位置(即将数组引用赋值给ab)
4: aload_1 //将ab压栈(ab.length调用)
5: arraylength //ab出栈,获取数组长度(具体长度获取由jvm获取),将数组长度压栈
6: istore_2 //变量存贮数组长度到索引2位置
7: return
LineNumberTable:
line 3: 0
line 4: 7

}

编译器也可以对Array.length()这样的语法做特殊处理,直接编译成arraylength指令。这样的话,我们就可 以使用方法调用的风格获取数组的长度了,这样看起来貌似也更加OO一点。那为什么不使用Array.length()的语法呢?也许是开发Java的那帮 天才对.length有所偏爱,或者抛硬币拍脑袋随便决定的吧。 形式不重要,重要的是我们明白了背后的机理。

java要比c/c++中的数组更安全,Java使用特定的指令访问数组的元素,这些指令都会对数组的长度(arraylenth)进行检查,java.lang.ArrayIndexOutOfBoundsException

汇编书籍推荐>王爽

分享到:
评论

相关推荐

    java初学者必看

    6.2 二维数组和多维数组 6.2.1 二维数组的声明 6.2.2 二维数组的初始化 6.2.3 二维数组的空间模型 6.2.4 二维数组的使用 6.3 数组操作 6.3.1 排序数组 6.3.2 查找 6.3.3 复制数组 6.3.4 填充数据 6.3.5 ...

    21天学通Java-由浅入深

    继续语句执行 79 4.7 综合练习 79 4.8 小结 80 4.9 习题 81 第5章 数组(精彩视频:52分钟) 83 5.1 如何创建数组 83 5.1.1 创建数组 83 5.1.2 创建多维数组 84 5.2 数组的初始化 85 5.2.1 创建并初始数组元素 85 ...

    Java语言的科学与艺术 斯坦福大学经典教材

    10.10 复习题 10.11 编程练习 第11章 数组与ArrayList类 11.1 数组简介 11.2 数组的内部表示法 11.3 数组作为参数传递 11.4 使用数组制作表格 11.5 数组初始化 11.6 多维数组 11.7 图像处理 11.8 ArrayList类 11.9 ...

    Java入门教程(微学苑)-part1

    1.6.1.1 J2SE(Java 2 Platform Standard Edition) 标准版 4 1.6.1.2 J2EE(Java 2 Platform Enterprise Edition) 企业版 4 1.6.1.3 J2ME(Java 2 Platform Micro Edition) 微型版 4 1.7 Java开发环境搭建 4 1.8 JDK 的...

    Java优化编程(第2版)

    5.4.3 在jni本地方法中访问数组 5.4.4 jni中的主要方法 5.5 jni中的重要技术 5.5.1 局部引用与全局引用 5.5.2 处理本地方法引起的java错误 5.5.3 线程与本地方法 5.6 jni数学计算与性能优化 5.7 处理好jni中的中文...

    【05-面向对象(下)】

    Lambda表达式来创建对象,该表达式创建出来的对象的目标类型就是这个函数式接口。 •Lambda表达式有如下两个限制:  –Lambda表达式的目标类型必须是明确的函数式接口。  –Lambda表达式只能为函数式接口...

    java面试题

    Struts1只是在第一次请求的时候创建一个action实例,以后每次相同的请求都直接从内存中去读取,它是单例模式,安全性较差。 Struts2是如何实现MVC模式的? 答:在Struts2里面是将每次页面的请求进行处理,然后将请求...

    JAVA面试题最全集

    除了使用new关键字创建对象意外,试列举另外三种以上创建实例的方式? 37.classloader中,JDK的API、Classpath中的同web-inf中的class加载方式有什么区别? 38.列举三种以上垃圾回收算法,并比较其优缺点? 39....

    java jdk实列宝典 光盘源代码

    创建文件和目录;删除文件和目录;移动文件和目录; 复制文件和目录;一个简单的文件搜索器; 多种方式读文件内容, 按字节读取文件内容、按字符读取文件内容、按行读取文件内容、随机读取文件内容; 多种方式写文件...

    Java JDK实例宝典

    3 创建文件和目录 7. 4 删除文件和目录 7. 5 移动文件和目录 7. 6 复制文件和目录 7. 7 一个简单的文件搜索器 7. 8 读文件 7. 9 写文件 7. 10 添加内容到文件尾 7. 11 文件的分割...

Global site tag (gtag.js) - Google Analytics