当前位置: 首页 > 图灵资讯 > 技术篇> 区分引用类型和原始类型

区分引用类型和原始类型

来源:图灵教育
时间:2024-02-22 14:39:45

Java提供两种不同的类型:引用类型和原始类型(或内置类型)。此外,Java还为每种原始类型提供包装类型(Wrapper)。假如需要一个整形变量,是使用基本的int型,还是使用一个Integer类的对象?如果需要声明一种布尔类型,是使用基本的boolean,还是使用boolean?这篇文章可以帮助你做决定。 下表列出了原始类型及其对象包装类型。 封装类原始类型及封装类原始类型 booleanBoolean charCharacter byteByte shortShort intInteger longLong floatFloat doubleDouble 引用类型与原始类型完全不同,具有不同的语义。例如,假设一种方法中有两个局部变量,一个是int的原始类型,另一个是引用integer对象: inti=5;//原始类型 Integerj=newInteger(10);///引用对象 这两个变量都存储在局部变量表中,都是在Java操作堆栈中操作的,但对它们的表示却完全不同。(以下部分将用通用术语堆栈代替操作数堆栈或局部变量表。)引用各占堆栈的32位原始类型int和对象。Java虚拟机至少需要32位存储才能实现一个int或一个对象引用。)Integer对象的堆栈项不是对象本身,而是对象的引用。 Java中的所有对象都应通过对象引用访问。对象引用是指向对象存储在堆中的某个区域的指针。当声明原始类型时,声明类型本身的存储。前两行代码表示如下: 引用类型和原始类型具有不同的特征和用法,包括:大小和速度问题,当引用类型和原始类型用作某一类别的实例数据时,该类型的数据结构存储指定的缺失值。对象引用实例变量的缺省值为null,而原始类型实例变量的缺省值与其类型有关。 许多程序的代码将包含原始类型及其对象包装。当检查它们是否相等时,使用这两种类型并了解它们如何正确地相互作用和共存将成为一个问题。为了避免代码错误,程序员必须了解这两种类型是如何工作和相互作用的。 例如,不能调用原始类型的方法,但可以调用对象的方法: intj=5; j.hashCode();//错误 //... Integeri=newInteger(5); i.hashCode();//正确 使用原始类型不需要调用new或创建对象。节省时间和空间。原始类型和对象的混合使用也可能导致与赋值相关的意想不到的结果。似乎没有错误的代码可能无法完成你想做的事情。例如: importjava.awt.Point; classAssign { publicstaticvoidmain(Stringargs[]) { inta=1; intb=2; Pointx=newPoint(0,0); Pointy=newPoint(1,1);//1 System.out.println("ais"+a); System.out.println("bis"+b); System.out.println("xis"+x); System.out.println("yis"+y); System.out.println("Performingassignmentand"+ "setLocation..."); a=b; a++; x=y;//2 x.setLocation(5,5);//3 System.out.println("ais"+a); System.out.println("bis"+b); System.out.println("xis"+x); System.out.println("yis"+y); } } 该代码生成以下输出: ais1 bis2 xisjava.awt.Point[x=0,y=0] yisjava.awt.Point[x=1,y=1] PerformingassignmentandsetLocation... ais3 bis2 xisjava.awt.Point[x=5,y=5] yisjava.awt.Point[x=5,y=5] 修改整数a和b的结果没有什么意外。b的值被赋予整形变量a,a的值增加了1。b的值被赋予整形变量a,a的值增加了1。这个输出反映了我们想要发生的事情。但令人惊讶的是,在赋值并调用setlocation后,x和y对象的输出。完成x=y赋值后,我们专门调用setlocation进行x=y赋值。x和y的值怎么会一样?毕竟,我们把y给x,然后改变x,这与我们对整数a和b的操作没有什么不同。 这种混淆是由使用原始类型和对象引起的。赋值对这两种类型的作用没有什么不同。但它可能看起来都不一样。赋值使等号(=)左侧等于右侧。对于原始类型(如inta和b)来说,这一点是显而易见的。对于非原始类型(如Point对象),赋值修改的是对象引用,而不是对象本身。因此,在句子中 x=y; 之后,x等于y。换言之,由于x和y是对象引用,它们现在引用相同的对象。因此,X所做的任何改变都会改变y。以下是//1代码执行后的情况: 执行//2分配后的情况如下: 在//3处调用setlocation时,这种方法是对x引用的对象执行的。由于x引用的Point对象也是y引用的对象,所以我们现在得到以下结果: 由于x和y引用相同的对象,因此x执行的所有方法和y执行的方法都作用于相同的对象。 区分引用类型和原始类型,理解引用的语义是非常重要的。如果做不到这一点,编写的代码将无法完成预定工作。 作者简介 IBM高级软件工程师PeterHagar。目前,他正在研究新兴的Java和因特网技术,并是IBM实时Java参考项目的主持人。他有丰富的编程经验,从事开发工具、类库和操作系统。在许多行业研讨会上,他经常就Java和其他技术发表技术演讲。1987年,他在纽约获得了Clarkson大学计算机科学学士学位。可以通过[email protected]与他联系。