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
汇编书籍推荐>王爽
分享到:
相关推荐
提供的视频文件01_一维数组内存分析.avi可能详细解释了数组在内存中的存储方式,02_数组元素的创建和使用.avi则演示了数组的创建和元素操作,03_练习_1.avi、04_练习_2.avi和05_练习_3.avi可能是针对数组操作的实践...
《J2SE 5.0 第05章:数组3》是Java编程学习的重要章节,主要探讨了数组这一核心概念的深入应用。在Java中,数组是一种存储同一类型数据的集合,可以是一维、二维甚至是多维的。在这个章节中,我们将重点关注二维数组...
J2SE 1.5允许在方法签名中使用省略号(...),创建可变参数的方法。这使得方法可以接受任意数量的相同类型的参数,如public void printNumbers(int... nums)。 七、静态导入(Static Import) 静态导入允许将类的...
- **ArrayList、LinkedList、Vector**:不同类型的动态数组实现,它们之间的性能差异及适用场景。 - **HashMap、HashTable、TreeMap**:理解散列和比较策略,以及不同映射结构的特性和用途。 - **Set接口**:...
3. **数组与集合**:数组用于存储固定数量的同类型元素,而集合框架(如ArrayList、LinkedList、HashSet、HashMap等)则提供了更灵活的数据结构。 4. **异常处理**:Java中的try-catch-finally结构用于捕获和处理...
2. 数组初始化简化:可以直接通过`= {元素列表}`的方式创建和初始化数组,如`int[] array = {1, 2, 3};` 四、异常处理 1. 多异常捕获:在catch子句中,可以同时捕获多种类型的异常,如`catch (IOException | ...
- 数组的定义及使用笔记:深入解析了数组的创建、初始化和使用,包括一维数组、多维数组以及数组的操作。 - 方法的声明及使用笔记:介绍了方法的定义、参数传递、返回值以及重载的概念,帮助理解方法在程序中的...
`ArrayList`是动态数组,允许在任意位置插入和删除元素;`HashMap`则实现了键值对的存储,提供快速查找功能。理解这些类的使用方式和特性对于日常编程至关重要。 2. **面向对象**: 面向对象编程是Java的基础,...
- **动态代理**:J2SE 6.0引入了动态代理,可以创建符合特定接口的代理对象,实现运行时方法拦截,方便进行AOP(面向切面编程)。 - **NIO.2**:新增了Java.nio.file包,提供了更高级别的文件操作API,支持文件系统...
这个平台包含了Java语言的核心库,提供了基础的类库、API以及运行时环境,使得开发者能够创建、运行和部署基于Java的应用程序。J2SE 5.0是Java发展中的一个重要版本,它引入了许多新的特性和改进,极大地提升了开发...
4. **数组**: 示例演示了单维和多维数组的创建、遍历和操作。 5. **函数(方法)**: 如何定义、调用方法,理解参数传递机制,以及了解重载和重写的概念。 6. **异常处理**: 使用try-catch-finally语句处理程序中的...
- **构造器**:用于初始化新创建的对象,与类名相同且无返回类型。 - **构造器重载**:提供多个构造器,每个具有不同的参数列表。 五、继承: - **单继承与多层继承**:Java 中类只能单继承,但可以通过接口实现...
文件“sxArrayList.java”可能涉及了ArrayList和HashMap的使用,ArrayList是动态数组,而HashMap则是基于哈希表实现的键值对存储。理解哈希函数的工作原理以及如何处理哈希冲突是深入学习哈希表的基础。 其他文件如...
- `ArrayList`是常用的动态数组实现,提供了一系列用于操作列表的方法。 - Java集合框架还包括`HashMap`、`HashSet`等数据结构,用于高效地存储和检索数据。 以上这些知识点涵盖了J2SE学习的基础和进阶内容,对于...
开发者可以利用这些组件创建游戏界面,包括游戏棋盘、计时器、得分显示等。 3. **事件处理机制** 游戏中的交互操作,如点击棋子进行匹配,需要用到Java的事件监听器和处理器。通过实现特定的Listener接口(如...
3. **数组和集合**:理解数组的基本操作,并使用ArrayList、LinkedList、HashSet等集合类。 4. **类和对象**:创建自定义类,实现方法,进行对象实例化和方法调用。 5. **异常处理**:编写包含异常处理的代码,体验...
本资源包是一套全面的J2SE(Java Standard Edition)基础教程,适合初学者深入学习Java编程。它包含了从基本语法到高级特性的多个主题,帮助初学者逐步掌握Java编程的核心知识。 1. **第二章 Java语法基础**:这...
在J2SE中,Java AWT(Abstract Window Toolkit)和Swing库提供了创建图形用户界面的工具。开发者可能会使用`javax.swing.JFrame`作为主窗口,`JPanel`作为游戏面板,并自定义组件如`JButton`来控制游戏的开始、暂停...
3. **数组与集合框架**:讲解了数组的基本操作以及ArrayList、LinkedList、HashSet、HashMap等集合类的使用,以及迭代器(Iterator)和泛型。 4. **字符串处理**:String类的特性,如不可变性、常用方法(substring...
J2SE包含了Java语言的核心库,如Java.lang、Java.util、Java.io等,同时提供了丰富的API,使得开发者能够创建功能强大的应用程序。 在“J2SE金典例题(包括注释),自己看的时候做的每个例题”这个压缩包中,你可以...