实践 8:区别 reference型别和 primitive型别
Java提供了截然不同的型别: reference(引用)型别和primitive(基本)型
别,后者又称为built-in(内置)型别。每一种primitive(基本)型别分别
拥有相应的外覆类( wrapperclasses) 。
import java.awt.*;
public class AssignTest {
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]
实践 9: 区分==和 equas()
请使用==测试两个基本型别是否完全相同( identical) ,或测试两个 object references是否指向同一个对象;、
请使用 equals()比较两个对象是否一致( same) ——基准点是其属性( attributes。译注:此处是指对象的实值内容,也就是数据值域, field) 。我们把[根据属性来比较两个对象是否相等]称为[等值测试]( testing forvalue) ,或称为[语义上的相等测试]
( testing for semantic equality) 。
实践 10:不要依赖 equals()的缺省实现
本例中的Golfball对象并没有实现自己的 equals(),因此调用的是 java.lang.Object的 equals(),结果不相等。
实现了类的equals,比较相关的必要属性,结果就相等了。
记住,你不一定要检查对象内的所有值域( fields) ,只需检查必要值域即可。
public class GolfBallTest {
private String brand;
private String make;
private int compression;
public GolfBallTest(String str, String mk, int comp) {
brand = str;
make = mk;
compression = comp;
}
public String getBrand() {
return brand;
}
public String getMake() {
return make;
}
public int getCompression() {
return compression;
}
// public boolean equals(Object obj) {
// if(this == obj)
// return true;
// if(obj != null && getClass() == obj.getClass()) {
// GolfBallTest gb = (GolfBallTest)obj;
// if(brand.equals(gb.getBrand()) &&
// make.equals(gb.getMake()) &&
// compression == gb.getCompression()) {
// return true;
// }
// }
// return false;
// }
public static void main(String[] args) {
GolfBallTest gb1 = new GolfBallTest("brandx", "professional", 100);
GolfBallTest gb2 = new GolfBallTest("brandx", "professional", 100);
if(gb1.equals(gb2)) {
System.out.println("gb1 is equals with gb2");
}
else {
System.out.println("gb1 is not equals with gb2");
}
}
}
gb1 is not equals with gb2 //没有实现 equals
gb1 is equals with gb2 //实现 equals
实践 11:实现 equals()时必须深思熟虑
实践 12:实现 equals()时优先考虑使用getClass()
强型别参数( strong argument)可以做到[唯有相同 class所产生的对象才得被视为相等]。 进一步的推论就是: 如果两个对象隶属不同的classes或types,则它们必不相等。对于实现equals()而言, [唯有相同 class所产生的对象才得被视为相等]是一个既轻松又简单的方案。为了达成这一点,必须在equals()实现代码中使用 getClass()。事实上,实践 10的 equals()实现代码中就已经用上了 getClass()。
实践 13:调用 super.equals()以唤起base class的相关行为
public class GolfBallTest {
private String brand;
private String make;
private int compression;
public GolfBallTest(String str, String mk, int comp) {
brand = str;
make = mk;
compression = comp;
}
public String getBrand() {
return brand;
}
public String getMake() {
return make;
}
public int getCompression() {
return compression;
}
public boolean equals(Object obj) {
if(this == obj)
return true;
if(obj != null && getClass() == obj.getClass()) {
GolfBallTest gb = (GolfBallTest)obj;
if(brand.equals(gb.getBrand()) &&
make.equals(gb.getMake()) &&
compression == gb.getCompression()) {
return true;
}
}
return false;
}
public static void main(String[] args) {
GolfBallTest gb1 = new GolfBallTest("brandx", "professional", 100);
GolfBallTest gb2 = new GolfBallTest("brandx", "professional", 100);
if(gb1.equals(gb2)) {
System.out.println("gb1 is equals with gb2");
}
else {
System.out.println("gb1 is not equals with gb2");
}
}
}
public class MyGolfBallTest extends GolfBallTest {
public static final byte TwoPiece = 0;
public static final byte ThreePiece = 1;
private byte ballConstruction;
public MyGolfBallTest(String str, String mk,
int comp, byte construction) {
super(str, mk, comp);
ballConstruction = construction;
}
public byte getBallConstruction() {
return ballConstruction;
}
// public boolean equals(Object obj){
// if (this == obj)
// return true;
// if (obj!=null && getClass()==obj.getClass() && super.equals(obj)) {
// MyGolfBallTest mg = (MyGolfBallTest)obj;
// if (ballConstruction == mg.getBallConstruction()) {
// return true;
// }
// }
// return false;
// }
public boolean equals(Object obj){
if (super.equals(obj)) {
MyGolfBallTest mg = (MyGolfBallTest)obj;
if (ballConstruction == mg.getBallConstruction()) {
return true;
}
}
return false;
}
public static void main(String[] args) {
MyGolfBallTest mg1 = new MyGolfBallTest("brandx", "professional", 90, MyGolfBallTest.TwoPiece);
MyGolfBallTest mg2 = new MyGolfBallTest("brandx", "professional", 100, MyGolfBallTest.TwoPiece);
if (mg1.equals(mg2)) {
System.out.println("mg1 is equals with mg2");
}
else
{
System.out.println("mg1 is not equals with mg2");
}
}
}
实践 14:在 equals()函数中谨慎使用instanceof
在equals()函数中使用getClass(),这种做法使得只有隶属同一个 class的对象才能被视为相等。
在equals()函数中使用instance of ,可以使得 derivedclass对象与其basecalss对象也可被视为相等,面总结了三种[在derivedclasses的equals()中采用instanceof做法]的情形:
1.Baseclass实现了equals(),而derivedclass没有。
假设baseclass的equals()使用instanceof, 那么你可以将derivedclass对
象与baseclass对象进行比较,这种比较是对称的(译注:亦即如果 b
相等于d,则d必然相等于b)。
2. Baseclass和derivedclass都实现了equals()。
如果两个classes都在equals()中使用instanceof,当你将derivedclass对象和baseclass对象进行比较时,你希望返回false。由于Base对象并非Derived实体,因此调用derivedclassequals()时的确会返回false。然而当调用baseclassequals()时,返回的确是true。究竟哪一个equals()被调用,取决于equals()调用句中的objectreference的位置。 (译注:让我多
做一点说明, 假设b是baseclass对象,d是derivedclass对象,d.equals(b)
和b.equals(d)分别调用的是derivedclass和baseclass的equals(),只是
因为b和d位置不同而造成的。 )
3. Baseclass并未实现equals(),但derivedclass实现了它。
由于Base对象并非Derived实体, 因此调用derivedclassequals()会返回false。调用baseclassequals()也会返回false,但两者原因并不相同。由于baseclass并未实现equals(), 所以调用的是java.lang.Object的equals(),他所比较的是两个objectreferencees相等与否
实践15. equals () 时需要遵循某些规则
、