讨论一下 Java 中的数组和 Array 类的关系如何?

Phoenix2000 2004-09-01 09:39:18
Java 中的数组用起来很方便,但是我有一次想得到数组的长度,查了一下资料,说每个数组都有一个 length 属性,试验了没错。而在 SUN 的 J2SE API 中,没有找到任何关于数组的 length 属性的介绍。我理解为,Java 中的数组其实也是一个 Object 对象,但是在 J2SE API 中查 Object 类并没有 length 属性。我倒是找到了 java.lang.reflect.Array 这个反射类,它提供的用于数组的静态方法太多了,里面的 getLength() 正是用于返回数组长度的,以下是我的测试:

import java.lang.reflect.*;

public class ArrayTest
{
public static void main(String args[])
{
int i_l1 = args.length; // 直接用数组对象的 length 属性
int i_l2 = Array.getLength(args); // getLength() 是 Array 反射类的静态方法
System.out.println("args.length = " + i_l1);
System.out.println("Array.getLength(args) = " + i_l2);
}
}

命令行下输入:
javac ArrayTest
java ArrayTest aaa bbb ccc

返回结果证明两种方式都得到正确的数组长度。不知道大家是怎么理解数组对象的 length 属性的?它是从哪冒出来的?难道是通过某种内在方式和反射类 java.lang.reflect.Array 挂钩?如果说直接声明 Object obj[] 这样的数组对象,那么 obj 对象属于什么类型?这个类型有 length 属性,怎么去查证?我用 java.lang.reflect.Array 的静态方法获取数组长度或者别的处理都肯定没有问题。
...全文
580 10 打赏 收藏 举报
写回复
10 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
zhushizu 2004-09-01
是呀,我也是想了好久。。关注中。。。
  • 打赏
  • 举报
回复
射天狼 2004-09-01
学习!
  • 打赏
  • 举报
回复
launch401 2004-09-01
数组应该是一种基本类型,就和int, boolean等一样,数组的length我想应该存在数组的存储空间中(就是存放数组成员reference的空间中,不知道是不是堆?)
  • 打赏
  • 举报
回复
kingfish 2004-09-01
Object obj[]
就是 Object[] obj, obj类型是[Ljava.lang.Object (认为length是这种类型的一个属性)

Array里的好多方法都是native的(包括getLength())
  • 打赏
  • 举报
回复
Phoenix2000 2004-09-01
虽然是个基础的问题,不过我始终想弄明白数组对象的 length 属性从哪里来的?因为我在 sun 的 j2se api 里面找不到数组对象的 length 直接描述?想不通啊。
  • 打赏
  • 举报
回复
Phoenix2000 2004-09-01
命令行写错了,应该是
javac ArrayTest.java
java ArrayTest aaa bbb ccc

这样 main() 的 args 数组就有三个字符串元素了。输出结果两种方法都返回 3。
  • 打赏
  • 举报
回复
Phoenix2000 2004-09-01
to mor(安稼):
非常感谢你的解答!目前我只是对数组使用 java.lang.reflect.Array,感觉效果挺好的,呵呵。
  • 打赏
  • 举报
回复
mor 2004-09-01
To Phoenix2000:
我在IBM developerWorks中国网站也看到过这篇文章:
《Java编程的动态性,第2部分:引入反射》
http://www-900.ibm.com/developerWorks/cn/java/j-dyn0603/
不知道你看的是不是这篇,我感觉这篇文章主要是讲解reflect的技术要点的,虽然在结束语里说了一下reflect的优缺点,但是并没有展开讨论。建议看Joshua Bloch的《Effective Java》,其中的第35条。reflect包的确提供了很强大的功能,但在实际应用中除非要用到某些事先不知道类型的对象实例,一般情况下,reflect包由于可能会带来严重的副作用而不被提倡。

我不知道你有没有用过JBoss,它的jmx-console里的许多页面上的那些invoke按钮明显是从java.lang.reflect.Method.invoke()来的,呵呵。
  • 打赏
  • 举报
回复
Phoenix2000 2004-09-01
如果是这么说的话,那倒很有道理,但只能说这是个隐含的或者非正式的调用方式,起码我在 Sun 的正式文档中并没看到啊,也可能是我没找到。而我是很自然地通过 Java 语言的基本类型映射联想到数组类型可能会有对应的 Object 派生类来做处理,结果找到了 java.lang.reflect.Array 这个反射类,并且这个类的全部方法都是静态的,专门来处理数组的创建、读写等等,动态数组也是支持的。我猜想可能 Java 内部某个层面(不是深层啊)上对数组的处理是不是通过这个反射类来的?我在 IBM 开发者网站上找到一篇关于 Java 反射类的应用,我看了还不是很明白,但第一感觉是反射类很重要,其功能可能还比较大。另外 java.lang.reflect.Array 和 java.lang.util.Array 不是一回事啊。
  • 打赏
  • 举报
回复
mor 2004-09-01
瞎说说:
上午看到这个问题,很惭愧,以前还真没有认真想过数组的length属性的问题。中午休息的时候查了点资料:
看了CSDN:xm4014的TIJ的学习笔记,认识到JAVA的内存分配策略有三种:静态的,栈式的,和堆式的。这里不讨论静态的内存分配,除非是要声明一个static的数组,不然与静态分配是无关的。按照xm4014的理解,JVM在运行应用程序时,同时处理栈分配和堆分配的。比如我们调用某个方法时,运行此方法的线程就会在栈里压入一个帧,这个帧里存储有被调用方法所需要的参数,局部变量,需要调用的其他方法等等。如果方法中声明了一个基本类型变量比如int,或者char之类的,那么就直接在栈的当前帧里分配内存。而如果方法中申请一个对象时,则在当前帧里分配一个句柄对象,而真正的对象内存空间是JVM到堆上分配的。
TIJ中提到数组是说“…… the array identifier is actually a reference to a true object that’s created on the heap……Part of the array object (in fact, the only field or method you can access) is the read-only length member that tells you how many elements can be stored in that array object.……”
我的理解是在声明一个数组时(String[] a = new String[5];),JVM在栈中生成一个int[]的对象句柄,同时在堆上分配一个int[]堆对象。这个堆对象中唯一可以访问的就是只读的length属性。虽然此时数组里还没有任何对象,但堆对象已经存在了。还有像String[] b = a;就很好理解了,两个栈里的句柄a和b都指向同一个堆对象。

java.lang.reflect.Array对象我没用过,倒是java.util.Arrays对象常用,做些排序什么的。
  • 打赏
  • 举报
回复
相关推荐
发帖
Java SE

6.2w+

社区成员

Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
帖子事件
创建了帖子
2004-09-01 09:39
社区公告
暂无公告