java-基础-数组探究

简介: 数组用new关键字创建并且组装,使用整形索引来访问,大小不可变,注意经常出现的数组越界问题。int [] a = new int[2];int [] a = new int{1,2,3,4}数组是一个简单的复合数据类型,一系列有序数据的集合,每个数具有相同的数据类型。

数组用new关键字创建并且组装,使用整形索引来访问,大小不可变,注意经常出现的数组越界问题。

int [] a = new int[2];
int [] a = new int{1,2,3,4}

数组是一个简单的复合数据类型,一系列有序数据的集合,每个数具有相同的数据类型。也是一个对象,既然数组都是对象,那么数组的类究竟是什么呢?当然不是java.util.Arrays啦!我们以int一维数组为例,看看究竟。

public class Main {   
    public static void main(String args[]){   
        int a[] = new int[10]; 
        Class clazz = a.getClass();   
        System.out.println(clazz.getName());   
    }   
}  
在SUN JDK 1.6上运行上述代码,输出为:

[I

看起来数组的类很奇怪,非但不属于任何包,而且名称还不是合法的标识符(identifier)。具体的命名规则[1]可以参见java.lang.Class.getName()的javadoc。简单的说,数组的类名由若干个’[‘和数组元素类型的内部名称组成,’[‘的数目代表了数组的维度。
具有相同类型元素和相同维度的数组,属于同一个类。如果两个数组的元素类型相同,但维度不同,那么它们也属于不同的类。如果两个数组的元素类型和维度均相同,但长度不同,那么它们还是属于同一个类。

数组的类有哪些成员呢?

public class Main {   
    public static void main(String[] args) {   
        int a[] = new int[10]; 
        Class clazz = a.getClass();   
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());   
}   
}  
0 
0 
0 
0 
0 
class java.lang.Object  

可见,[I这个类是java.lang.Object的直接子类,自身没有声明任何成员变量、成员方法、构造函数和Annotation,可以说,[I就是个空类。
“为什么获取数组的长度用.length(成员变量的形式),而获取String的长度用.length()(成员方法的形式)?”
想必编译器对Array.length进行了特殊处理.
JVM自己在运行时生成的了。JVM生成类还是一件很容易的事情,甚至无需生成字节码,直接在方法区中创建类型数据,就差不多完工了。

The JavaTM Virtual Machine Specification Second Edition

类加载器先看看数组类是否已经被创建了。如果没有,那就说明需要创建数组类;如果有,那就无需创建了。
如果数组元素是引用类型,那么类加载器首先去加载数组元素的类。
JVM根据元素类型和维度,创建相应的数组类。
JVM创建了[I类。JVM不把数组类放到任何包中,也不给他们起个合法的标识符名称,是为了避免和JDK、第三方及用户自定义的类发生冲突吧。JVM也必须动态生成数组类,因为Java数组类的数量与元素类型、维度(最多255)有关,相当相当多了,是没法预先声明好的.

Array.length这样的语法如何通过编译,如何执行的呢?

JVM没有为数组类生成length这个成员变量.

public class Main {   
    public static void main(String[] args)   
    {  
       int a[] = new int[2]; 
       int i = a.length;   
    }   
}  
0 iconst_2                   //将int型常量2压入操作数栈  
1 newarray 10 (int)    //将2弹出操作数栈,作为长度,创建一个元素类型为int, 维度为1的数组,并将数组的引用压入操作数栈  
3 astore_1                 //将数组的引用从操作数栈中弹出,保存在索引为1的局部变量(即a)中  
4 aload_1                  //将索引为1的局部变量(即a)压入操作数栈  
5 arraylength            //从操作数栈弹出数组引用(即a),并获取其长度(JVM负责实现如何获取),并将长度压入操作数栈  
6 istore_2                 //将数组长度从操作数栈弹出,保存在索引为2的局部变量(即i)中  
7 return                    //main方法返回  

字节码中,根本就没有看见length这个成员变量,获取数组长度是由一条特定的指令arraylength实现。编译器对Array.length这样的语法做了特殊处理,直接编译成了arraylength指令。另外,JVM创建数组类,应该就是由newarray这条指令触发的了。

目录
相关文章
|
20天前
|
移动开发 Java Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【4月更文挑战第3天】在移动开发领域,性能优化一直是开发者关注的焦点。随着Kotlin的兴起,其在Android开发中的地位逐渐上升,但关于其与Java在性能方面的对比,尚无明确共识。本文通过深入分析并结合实际测试数据,探讨了Kotlin与Java在Android平台上的性能表现,揭示了在不同场景下两者的差异及其对应用性能的潜在影响,为开发者在选择编程语言时提供参考依据。
|
1月前
|
Java 编译器 Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【2月更文挑战第30天】 随着Kotlin成为开发Android应用的首选语言,开发者社区对于其性能表现持续关注。本文通过深入分析与基准测试,探讨Kotlin与Java在Android平台上的性能差异,揭示两种语言在编译效率、运行时性能和内存消耗方面的具体表现,并提供优化建议。我们的目标是为Android开发者提供科学依据,帮助他们在项目实践中做出明智的编程语言选择。
|
28天前
|
Java 编译器 Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
在开发高性能的Android应用时,选择合适的编程语言至关重要。近年来,Kotlin因其简洁性和功能性受到开发者的青睐,但其性能是否与传统的Java相比有所不足?本文通过对比分析Kotlin与Java在Android平台上的运行效率,揭示二者在编译速度、运行时性能及资源消耗方面的具体差异,并探讨在实际项目中如何做出最佳选择。
17 4
|
3天前
|
存储 Java 程序员
Java 数组
4月更文挑战第16天
|
22天前
|
搜索推荐 Java
Java基础(快速排序算法)
Java基础(快速排序算法)
23 4
|
25天前
|
Java
java 8 数组转字符串并以逗号分隔
java 8 数组转字符串并以逗号分隔
11 0
|
29天前
|
算法 安全 Java
Java中的并发编程优化探究
本文深入探讨了Java中的并发编程优化策略,从锁机制到线程池的使用,以及常见的并发问题与解决方案。通过分析不同的优化方法,帮助开发者更好地应对并发环境下的挑战,提高程序性能和稳定性。
12 0
|
1月前
|
安全 Java 开发者
Java并发编程中的线程安全性探究
在Java编程中,线程安全性是一个至关重要的问题,涉及到多线程并发访问共享资源时可能出现的数据竞争和不一致性问题。本文将深入探讨Java并发编程中的线程安全性,介绍常见的线程安全性问题以及解决方法,帮助开发者更好地理解和应对在多线程环境下的挑战。
|
1月前
|
安全 Java 开发者
Java并发编程中的线程安全性探究
在Java开发中,多线程编程是一项常见且重要的技术。本文将深入探讨Java并发编程中的线程安全性问题,从数据竞争到同步机制的选择,帮助开发者更好地理解和应对多线程环境下的挑战。
13 2
|
1月前
|
Java
【Java】数组中的拷贝方法与初步理解深浅拷贝
【Java】数组中的拷贝方法与初步理解深浅拷贝
12 0