实例化对象讲解

实例化对象

在Java中,new关键字用于实例化一个对象。new运算符在内存中创建一个对象,并返回对新创建的对象的一个引用。只要我们的程序保留对该对象的一个引用,那么这个对象将一直保留在内存中。

下面的语句声明了一个Employee引用,并使用new关键字将该引用赋值给一个新的Employee对象:

 

Employee e;

e = new Employee();

引用e指向内存中的Employee对象。运算符new为该对象分配内存,然后将该对象的所有成员变量赋以初始值,这样,这些成员变量就不会包含垃圾数据。

表列出了各种数据类型的成员变量的初始值。

表4-1一个对象的成员变量的初始值

成员变量的数据类型

初始值

byte

0

short

0

int

0

long

0

float

0.0

double

0.0

char

空字符

boolean

false

任何类型的引用

null

实例化对象的两条语句可以合并为一条语句来实现。例如:

 

Employee e = new Employee();

这里我们之所以要分开为两条语句,是为了重点强调在实例化时实际上在内存中创建了两个实体:一个引用和一个对象。在两条语句的第一条语句中,e被声明为对一个Employee对象的引用,意思是e可以引用任何Employee对象。而第二条语句中,e被赋值了一个新的Employee对象。

2 理解引用

一个引用通常是一个包含它引用的对象的内存地址的32位整型值。这里说“通常”,是因为Java语言规范中没有严格定义一个引用的大小。在将来,引用可能会是64位或更大。同样,如果用在更小的电子设备中的操作系统中,引用可能比32位小。

引用本质上是整型。那么,为什么要将引用声明为一个特定的数据类型呢?这是因为Java中数据类型是严格强制的,一个引用必须是某种特殊的类数据类型。

例如,通过下面的语句,我们在内存中分配了两个Employee引用和一个String引用:

 

Employee e1, e2;

String s;

三个引用消耗相同的内存容量,并且实际上都是整型数据类型。但是,引用e1和e2只能引用Employee对象。引用s只能引用String对象。如果我们试图用下面的语句打破这个规则,是不能通过编译的:

 

 

s = new Employee();  //不能通过编译

e1 = "张三";           //不能通过编译

也许有人会认为使用强制类型转换运算符可以解决问题:

 

e1 = new Employee();  //有效

s = e1;                 //不能通过编译

s = (Employee) e1;  //还是不能通过编译

但是,编译器知道String对象和Employee对象是不兼容的,于是上面的语句中会发生编译错误。

而引用e1和e2是相同的数据类型,因此可以相互赋值。例如:

 

e1 = new Employee();

e2 = e1;    //有效

引用e1被赋值了一个新的Employee对象,引用e2被赋值为e1。这是有效的,因为e1和e2都是Employee引用,是相同的数据类型。这个新的Employee对象现在有两个引用指向它,如图4.1所示。注意,在内存中只有一个Employee对象,因为我们只能用new关键字一次。将e1赋值给e2不会创建一个新对象。


图4.1 引用相互赋值

我们还可以用一条语句来声明引用e,并初始化Employee对象:

 

Employee e = new Employee();

这条语句在内存中创建了两个分离的元素:引用e和Employee对象。引用e不是一个对象。对象本身并没有变量名,我们要访问和使用对象的唯一方式是使用对该对象的一个引用。

3 方法必须与某个对象关联

初学者最常见的一个错误是试图不使用一个引用就调用一个方法。在下面的代码片断中,第二条语句不能通过编译:

 

Employee e1 = new Employee(), e2 = new Employee();     //有效

mailCheck();          //错误。邮寄支票给谁?

在上面的代码行中,我们实例化了两个Employee对象,然后试图不使用引用就调用mailCheck()。首先,Java中这样做是不行的。在Java中要调用一个方法必须使用一个引用,除非该方法被声明为静态的(static)。在这种情况下,我们可以直接在方法前面用类名加上一个点运算符来调用方法。

其次,因为有两个Employee对象,所以就有两个mailCheck()方法。如果不指定恰当的引用和点运算符,那么编译器根本不知道我们到底要调用哪一个对象的方法。

与每个Employee对象有自己的name、address、salary等属性一样,每个Employee对象也有自己的mailCheck()和computePay()方法。要调用mailCheck(),我们就必须使用点运算符指定要调用哪个对象的mailCheck()方法。例如,下面的语句调用e1代表的Employee对象的mailCheck()方法:

 

e1.mailCheck();

下面的语句调用e2代表的Employee的mailCheck()方法:

 

e2.mailCheck();

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值