1).类的引用机制概述
一个原语类型的变量存储该类型的一个值。然而,一个类型的变量并不存储该类的对象。一个类类型的变量存储该对象在计算机内存中的位置的引用(存储地址)。这就使得一些操作,如=和==等,对一个类类型的变量所产生作用,与他们对一个原语类型的变量所产生的作用有很大的区别。(数组类型也是引用类型)
例如:
ToClass a=new ToClass(5); //ToClass的类是临时想出来的类
ToClass b;
b=a;
a.set(4); //改变a对象中的构造是赋值的变量
System.out.print(b);
==================
运行结果:
4 //说明这两个变量引用相同的对象,改变一个另一个也随之改变+
2).由引用机制所带来的方法参数传递的差异
java中参数都是值传递,但类类型传递的是引用,所以会出现很多不同。
也就是说方法不会改变原语类型的自变量的值,但是方法可以改变一个类类型的自变量的实例变量的值。
3).由引用机制所带来的隐私泄露(取值和赋值方法)
错误的取值和赋值方法会破坏类的私有变量, 例如:
1.取值
对于取值有两种不同的操作方法:
1).
pubic Date getBirthDate()
{
return new Date(born);
}
2).
public Date getBirthDate()
{
return born;
}
假如使用第二种操作方法,则直接后果就是外界能够随意修改类内修饰符为private的实例变量,并绕过Person类的构造方法和赋值方法的检查。例如:
Person citizen=new Person(“Joe”,1999);
Date dateName =citizer.getBirthDate();
dataName.setDate(1998);
而第一种方法不是返回实例变量的引用,他使用拷贝构造方法返回一个新的对象的引用,是born对象的副本。
这样一来若外界随意改变born对象的副本,born的对象实例也不会发生任何改变。
2.赋值
没有正确定义的构造方法或赋值方法也会引起隐私泄露。例如:
对于赋值的两种常用方法:
1).
public void setDate(Date newDate)
{
born =new Date(newDate);
}
2).
public void setDate(Date newDate)
{
born=newDate;
}
假如使用第二种复制方法,newDate与类的born实例变量具有相同的引用,由此可能不经意通过修改newDate而修改了born,这样会绕过类能赋值方法的检查,也使类的封装机制遭到破坏。
但是会发现一个奇怪的String类是特殊的,例如:
对照Person类和String的取值方法:
public String getName()
{
return name;
}
public Date getBirthDate()
{
return new Date(born);
}
发现String取值方法只返回引用,不会导致上面的隐私泄露吗???
Person cicizen=new Person();
String s=cicizer.getName();
这样看起来好像通过调用String的复制方法就能改变类内的私有数据。但是String类没有赋值方法,String类内包含的任何方法都不能改变一个String对象中的数据。
初看起来,似乎可以改变一个String对象中的数据。应该怎样应对已经遇到过的如下操作:
String greeting=“Hello”;
greeting =greeting +“friend”;
这里我们并没有把对象中的Hello改为Hello friend ,而是新创建了一个对象为Hello friend 。
查证过程如下:
String greeting =“Hello”;
String s=greeting; //与greeting相同的对象引用
greeting =greeting +“friend”;
System.out.print(s);
输出结果为:
Hello
这里涉及两个基本概念:
1).不可变类:类中包含的所有方法(除了构造函数)都不能改变类的对象中的数据。
2).可变类。
3).类类型的数组
Date[] hoildayList =new Date[20];
这将创建20个索引变量,而不是20个对象。