java-基础-数组探究

数组用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这条指令触发的了。

时间: 2024-10-29 11:35:13

java-基础-数组探究的相关文章

java基础问题,数组声明问题,突然卡住了?

问题描述 java基础问题,数组声明问题,突然卡住了? public class Test{ int[] a; //声明数组 //a = new int[10]; //这样引用数组是错的 public Test(){ a = new int[10]; //在构造函数里引用数组是对的 } public static void main(String[] args){ System.out.println(a.length); } } 这是什么原因 能不能详细解答一下 非常感谢!!! 解决方案 在一

程序猿的日常——Java基础之clone、序列化、字符串、数组

其实Java还有很多其他的基础知识,在日常工作技术撕逼中也是经常被讨论的问题. 深克隆与浅克隆 在Java中创建对象有两种方式: 一种是new操作符,它创建了一个新的对象,并把对应的各个字段初始化成默认值: 另一种是用clone方法,基于已有的对象创建一个新的对象,此时会根据原有的对象各个字段赋值给新的对象. 如果对象的字段都是基础类型,没有什么问题,但是如果字段是对象,那么其实clone的时候复制的仅仅是对象的引用而已. 上面就是深克隆与浅克隆的区别. 在我们日常的开发中,如果涉及到克隆,就需

JAVA学习(三):Java基础语法(变量、常量、数据类型、运算符与数据类型转换)

Java基础语法(变量.常量.数据类型.运算符与数据类型转换) 1.变量 Java中,用户可以通过指定数据类型和标识符来声明变量,其基本语法为: DataType identifier;  或  DataType identifier = value; 其中,DataType是变量类型,如int/string/char/double/boolean等:identifier是变量名称,即标识符:value就是声明变量的值. 注: a.标识符由数字0-9.大小写字母.下划线.美元符号.人民币符号以及

编程题-面试中碰到的java基础题

问题描述 面试中碰到的java基础题 今天面试碰到这么一个问题,想了半天,不知如何回答 P1=V1; P2=V2; method(P1,P2){ P1=V3; P2=V4; } 结果是P1=V1;P2=V4;问P1P2是什么类型的时候才会出现这种情况 解决方案 在传递的时候,如果传递的是原生数据类型,则值不会改变 public class Test { public static void main(String[] args) { int a = 1; int b = 2; swap(a,b)

Java基础之001-学习资源的选择

Java基础之001-学习资源的选择                                                                                                                            35岁学习Java       1. 工欲善其事,必先利其器        学习是一种能力.站在巨人的肩膀上,才能站的更高,走的更远.为了学习java,我在网络上探寻了很长时间,最终选择了传智播客的免费教学视频(绝非

java基础(数据类型,运算符)

java基础之数据类型(变量) java中存在的数据有常量和变量 常量:在程序执行的过程中其值不可以发生改变 常量的分类 字面值常量 字面值常量的分类 常量 描述 字符串常量 用双引号括起来的内容 整数常量 所有整数 小数常量 所有小数 字符常量 用单引号括起来的内容,里面只能放单个数字,单个字母或单个符号 布尔常量 较为特殊,只有true和false 空常量 null(数组部分) - - 自定义常量 变量:在程序执行的过程中,在某个范围内其值可以发生改变的量 定义格式: 数据类型 变量名 =

零基础轻松入门——JAVA基础学习

你准备好学习java了吗?了解一下开发java的基本过程以及java的基本特性.与C++做些简单的比较,熟悉两种语言的共性和区别,关于一些java知识体系. Java 的主要特性: 1. Java语言的语法与C语言和C++语言很接近,使得大多数程序员很容易学习和使用.另一方面,Java丢弃了C++中很少使用的.很难理解的.令人迷惑的那些特性,如操作符重载.多继承.自动的强制类型转换.特别地,Java语言不使用指针,而是引用.并提供了自动的废料收集,使得程序员不必为内存管理而担忧. 2.Java是

JAVA中数组问题

问题描述 我直接写内容:inta[]=newint[4];intb[]=newint[4];a.equals(b);false????第一个不懂为什么是FALSEinta[]=newint[]{1,2,3,4};intb[]=newint[]{1,2,3,4};a.equals(b);false????还是不懂为什么是FALSE帮帮的谢谢了 解决方案 解决方案二:equal不是只在String中才用到的吗?解决方案三:equals比较的值,a和b又不是一个值怎么比较啊?当然是false解决方案四

java 基础编程题,急求结果

问题描述 java 基础编程题,急求结果 1,int isVesuvian(int n),如果n是有且仅是两组不同的两个数的平方和,返回1,否则0. 2,int isOneBalanced(int a[]),判读数组是否是平衡数组,开头连续为1的数 + 结尾连续为1的数 = 中间连续不为1的数 结果返回1,否则为0. 3,int closestFibonacci(int n),返回比n小的最大的斐波拉契元素.斐波拉契数列 1 1 2 3 5 8 13 21 34 PS:1 1 2 3 5 8 1

java基础-请教方向(Java研发方向),初学者

问题描述 请教方向(Java研发方向),初学者 刚学了一学期Java, 想知道Java一般的学习过程是先学什么,后学什么比较合理.望不吝指教- 解决方案 1.变量 方法 逻辑分支语句 循环语句 运算符 逻辑运算符 基本数据类型 引用数据类型 数组 集合 ,基本语法必须要熟练掌握,这些东西可能是习惯养成 2.把类.抽象类.接口 继承 变量 方法 重写 重载 转型 ,结合面向对象以及内存角度来理解,面向对象就是从现实生活中对象之间关系引出的一种编程思想 最简单的理解就是 class就是种类的意思 用