怎么查看java的引用类_一段代码看 Java 引用类型

Java 中的操作数(不知道叫什么,相对于 bytecode 而言,类似 CPU 的操作码和操作数)分为值类型和引用类型:

值类型就是直接存储最终数值的,如 char, int, float, double...

引用类型包括了数组,以及其它所有用 class 定义的数据类型,这种数据类型由引用和对象实例连部分组成。

虽然 Java 中一切都是类,但是对于值类型,因为不需要存储其‘对象’特征,所以,编译器只为他们分配了 stack 上的空间,存储单个的值就可以了。而引用类型则不同,他们的变量存储分为两部分:在 stack 中的引用(指针),以及在 heap 中的对象实例。大概长这样(图借别人的,看最后的链接):

a8c6a96b89ae766439b57e1973675448.png

使用下面一段代码来理解这个问题,体会下区别(String.equals() 的标准实现)。

1 public booleanequals(Object anObject) {2 if (this ==anObject) {3 return true;4 }5 if (anObject instanceofString) {6 String anotherString =(String)anObject;7 int n =value.length;8 if (n ==anotherString.value.length) {9 char v1[] =value;10 char v2[] =anotherString.value;11 int i = 0;12 while (n-- != 0) {13 if (v1[i] !=v2[i])14 return false;15 i++;16 }17 return true;18 }19 }20 return false;21 }

一起从这段代码来看看值类型和引用类型的区别:

1. 第 2 行,首先使用 == 判断,两个引用指向的是否为同一个对象实例。

2. 第 5 行,判断传入的 object 是否是 String 的实例。

3. 第 6 行,将传入的 object 强制转换为 String 类。

4. 第 7、8 行,取 this.value.length 与 anotherString.value.length 作比较。value 的类型是 char[],因为数组是一个有限的数据集合,其定义时就已经固定了长度。所以这个操作被编译后,只是两个内存单元的内容比较。

5. 第 9、10 行,创建新的数组引用,分别指向 this.value 和 anotherString.value。

6. 第 11-16 行,逐个比较两个 char 数组中的元素。直接比较两个数组各个元素的效率,是要比比较 String 元素的效率更高的(转化为 Char 对象的比较,再比较 Char value,显然是要耗费更多资源的...)。

关于数组

数组是 JVM 提供的基本数据类型之一。

JVM 直接提供的数组类型有 T_BOOLEAN([Z, 1byte)、T_CHAR([C, 2bytes)、T_FLOAT([F, 4bytes)、T_DOUBLE([D,8bytes)、T_BYTE([B, 1bytes)、T_SHORT([S, 2bytes)、T_INT([I, 4bytes)、T_LONG([J, 8bytes)。

我们可以轻松验证,一个数组是 instanceof Object,同时,数组调用方法 getClass().getName(),也是可以正确输出的。

public classarrayTest {public static voidmain(String[] args) {int[] a = {1,2,3,4};

System.out.println(a.getClass().getName());

System.out.println("a is instanceof Object? "+(a instanceofObject));

}

}

当然,数组的实现方法是在 JVM 中的,但这并不妨碍我们像使用其它类/对象一样类使用数组。

一个 array 在内存中的 layout 大概长这样:

359a109a5cb1ce9b425f1a9ea204768e.png

从上面的图中,可以看到两个信息,第一个,数组在内存中是连续存放的,第二个,header 之后的位置存储着数组的长度。这也是为什么我们可以直接获取数组的 length 属性,而其它一些类,必须使用 length() 方法。

关于 length 存储空间的大小,这个显示是和 JVM 实现有关的。查阅文档发现,sun 的 JVM (java7) 版本:32位系统中 size_t 是4字节的,在64位系统中,size_t 是8字节的。

另外,好奇对象数组是怎样存的,打印了一下 String[] b 的 classNage,显示是“[Ljava.lang.String;”。其中 “[” 表示这是个数组,“L/java/lang.String;” 叫做 JavaNative Interface Field Descriptors,大概就是说这是个 String 类型的数组了。

创建数组的 bytecode 是 JAVA_NEWARRAY 和 JAVA_ANEWARRAY,暂作记录,改天有空再看看 JVM 中是怎么来操作的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值