`
java-mans
  • 浏览: 11977503 次
文章分类
社区版块
存档分类
最新评论

引用类型和原始类型

 
阅读更多

Peter Haggar
IBM 高级软件工程师
本文是从 Practical Java(Addison-Wesley 出版)一书节选改编而来的。

Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。另外,Java 还为每个原始类型提供了封装类(Wrapper)。如果需要一个整型变量,是使用基本的 int 型呢,还是使用 Integer 类的一个对象呢?如果需要声明一个布尔类型,是使用基本的 boolean,还是使用 Boolean 类的一个对象呢?本文可帮助您作出决定。

下表列出了原始类型以及它们的对象封装类。

原始类型 封装类
=================
boolean Boolean
char Character
byte Byte
short Short
int Integer
long Long
float Float
double Double

引用类型和原始类型的行为完全不同,并且它们具有不同的语义。例如,假定一个方法中有两个局部变量,一个变量为 int 原始类型,另一个变量是对一个 Integer 对象的对象引用:


int i = 5; // 原始类型
Integer j = new Integer(10); // 对象引用

这两个变量都存储在局部变量表中,并且都是在 Java 操作数堆栈中操作的,但对它们的表示却完全不同。(本文中以下部分将用通用术语堆栈代替操作数堆栈或局部变量表。)原始类型 int 和对象引用各占堆栈的 32 位。(要表示一个 int 或一个对象引用,Java 虚拟机实现至少需要使用 32 位存储。)Integer 对象的堆栈项并不是对象本身,而是一个对象引用。


Java 中的所有对象都要通过对象引用访问。对象引用是指向对象存储所在堆中的某个区域的指针。当声明一个原始类型时,就为类型本身声明了存储。前面的两行代码表示如下:

引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型有关。

许多程序的代码将同时包含原始类型以及它们的对象封装。当检查它们是否相等时,同时使用这两种类型并了解它们如何正确相互作用和共存将成为问题。程序员必须了解这两种类型是如何工作和相互作用的,以避免代码出错。


例如,不能对原始类型调用方法,但可以对对象调用方法:

int j = 5;
j.hashCode(); // 错误
//...
Integer i = new Integer(5);
i.hashCode(); // 正确

使用原始类型无须调用 new,也无须创建对象。这节省了时间和空间。混合使用原始类型和对象也可能导致与赋值有关的意外结果。看起来没有错误的代码可能无法完成您希望做的工作。例如:


import java.awt.Point;

class Assign
{
public static void main(String args[])
{
int a = 1;
int b = 2;
Point x = new Point(0,0);
Point y = new Point(1,1); //1
System.out.println("a is " + a);
System.out.println("b is " + b);
System.out.println("x is " + x);
System.out.println("y is " + y);
System.out.println("Performing assignment and " +
"setLocation...");
a = b;
a++;
x = y; //2
x.setLocation(5,5); //3

System.out.println("a is "+a);
System.out.println("b is "+b);
System.out.println("x is "+x);
System.out.println("y is "+y);
}
}


这段代码生成以下输出:


a is 1
b is 2
x is java.awt.Point[x=0,y=0]
y is java.awt.Point[x=1,y=1]
Performing assignment and setLocation...
a is 3
b is 2
x is java.awt.Point[x=5,y=5]
y is java.awt.Point[x=5,y=5]

修改整数 a 和 b 的结果没什么意外的地方。b 的值被赋予整型变量 a,结果 a 的值增加了 1。这一输出反映了我们希望发生的情况。但是,令人感到意外的,是在赋值并调用 setLocation之后 x 和 y 对象的输出。我们在完成 x = y 赋值之后特意对 x 调用了 setLocation,x 和 y 的值怎么会相同呢?我们毕竟将 y 赋予 x,然后更改了 x,这与我们对整数 a 和 b 进行的操作没什么不同。

这种混淆是由原始类型和对象的使用造成的。赋值对这两种类型所起的作用没什么不同。但它可能看起来所有不同。赋值使等号 (=) 左边的值等于右边的值。这一点对于原始类型(如前面的 int a 和 b)是显而易见的。对于非原始类型(如 Point 对象),赋值修改的是对象引用,而不是对象本身。因此,在语句

x = y;

之后,x 等于 y。换句话说,因为 x 和 y 是对象引用,它们现在引用同一个对象。因此,对 x 所作的任何更改也会更改 y。下面是 //1 处的代码执行以后的情况:

执行 //2 处的赋值以后情况如下:

当在 //3 处调用 setLocation 时,这一方法是对 x 引用的对象执行的。因为 x 引用的 Point 对象也正是 y 所引用的对象,所以我们现在得到以下结果:


因为 x 和 y 引用同一个对象,所以对 x 执行的所有方法与对 y 执行的方法都作用于同一个对象。


区分引用类型和原始类型并理解引用的语义是很重要的。若做不到这一点,则会使编写的代码无法完成预定工作。

分享到:
评论

相关推荐

    java笔试题 大学生应聘

    Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每个原始类型提供了封装类。 原始类型封装类,booleanBoolean,charCharacter,byte...

    C#中引用类型和值类型的区别

    在C#编程语言中,类型系统是其核心组成部分,它主要分为两大类:引用类型和值类型。这两种类型的差异在程序设计与优化中扮演着关键角色,了解它们的区别对于提高代码质量和性能至关重要。 ### 引用类型 引用类型在...

    值类型和引用类型的区别

    ### 值类型和引用类型的关键区别 #### 1. 定义与概念 - **值类型**: 在声明变量时,直接将值存储在该变量的内存位置中。这意味着值类型的变量直接持有其数据,无需通过引用间接访问。在.NET框架中,值类型包括所有...

    Java中的基本类型和引用类型变量的区别

    Java 中的基本类型和引用类型变量的区别 Java 中的基本类型和引用类型变量是两个不同的概念,它们在内存分配、变量赋值和函数传递等方面有着本质的区别。 基本类型是 Java 中的八种基本类型,包括 byte、short、...

    JAVA原始类型和引用类型有哪些区别?[定义].pdf

    Java编程语言中有两种基本的数据类型:原始...了解原始类型和引用类型之间的这些差异是编写高效、无错误的Java代码的关键。在设计和实现程序时,应根据具体需求和场景选择合适的数据类型,以确保代码的性能和正确性。

    Java笔试题目汇总

    引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数 据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始...

    史上最全Java面试题目大集合

    引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始...

    java面试笔试题大汇总

    引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始...

    JAVA知识点 重点复习

    引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。 字符串操作 Java平台提供了两个类:String...

    值类型与引用类型(.html)

    在C#编程语言中,值类型和引用类型是两种基本的数据类型,它们在内存管理和数据存储方式上有着显著的区别,这对于理解和优化代码性能至关重要。本文将深入探讨这两种类型的特性和应用场景。 1. 值类型(Value Types...

    引用类型传值方法

    在编程领域,我们经常需要处理各种数据类型,其中包括值类型(value types)和引用类型(reference types)。...在实际开发中,根据需求选择合适的类型和传值方式,可以有效地优化性能和降低错误率。

    最新java考试题目(找工作)

    7. 引用类型和原始类型的区别:Java 提供两种不同的类型:引用类型和原始类型。引用类型和原始类型的行为完全不同,并且它们具有不同的语义。 8. 运行时异常与一般异常的区别:运行时异常表示虚拟机的通常操作中...

    java经典笔面试题

    Java提供了两种不同的类型:引用类型和原始类型。原始类型包括byte、int、char、long、float、double、boolean和short。引用类型包括String、Integer、Long、Float、Double等。 四、String和StringBuffer的区别 ...

    引用类型与值类型的运算

    - 当值类型的数据与引用类型的数据进行运算时,系统会尝试调用引用类型的`valueOf`方法来获取一个原始值。这样做是为了尝试将引用类型转换为可以与值类型相匹配的数据形式。 - 如果转换成功并且返回值是可以进行...

    C#基础知识 值类型、引用类型

    本文将深入探讨C#中的核心概念:值类型和引用类型。这两种类型在内存管理和数据处理上有着显著的区别,理解它们对于编写高效且无错的代码至关重要。 值类型(Value Types)包括基本类型如整型(int)、浮点型...

    java葵花宝典(面试法宝)

    引用类型和原始类型的行为完全不同,并且它们具有不同的语义。 4. String和StringBuffer的区别 String类提供了不可修改的字符串,StringBuffer类提供的字符串可以进行修改。当你知道字符数据要改变的时候你可以...

    java笔试题目java笔试题目.doc

    2. 引用类型和原始类型:Java 提供两种不同的类型:引用类型和原始类型。int 是 Java 的原始数据类型,Integer 是 Java 为 int 提供的封装类。 字符串操作 1. String 和 StringBuffer 的区别:String 提供了数值不...

    java所有类型题库

    引用类型和原始类型的行为完全不同,并且它们具有不同的语义。 String和StringBuffer的区别 String和StringBuffer都是Java平台提供的类,用于存储和操作字符串。String类提供了不可变的字符串,而StringBuffer类...

    Java程序员面试宝典

    - **引用类型和原始类型的差异**:包括存储方式、默认值、处理速度等方面,引用类型默认值为null,原始类型有特定的默认值。 3. **异常处理** - **运行时异常与一般异常**:运行时异常是程序运行时可能出现的错误...

    CSDN.rar_简繁体_股票 java

    区分引用类型和原始类型 Java中的两个特殊变量this和super Java中利用散列表实现股票行情的查询 Java中文问题详解 Vector在Java编程中的应用 编写高级应用程序1 编写高级应用程序2 实现 Swing 的 JTables 和 ...

Global site tag (gtag.js) - Google Analytics