实践 1:参数以by value方式而非by reference方式传递
import java.awt.*;
public class PassByValue {
public static void ModifyPoint(Point pt, int j) {
pt.setLocation(5,5);
j = 15;
System.out.println("During modifyPoint " + "pt = " + pt + " and j = " + j);
}
public static void main(String[] args) {
Point p = new Point(0, 0);
int i = 10;
System.out.println("before modifyPoint " + "pt = " + p + " and i = " + i);
ModifyPoint(p, i);
System.out.println("after modifyPoint " + "pt = " + p + " and i = " + i);
}
}
before modifyPoint pt = java.awt.Point[x=0,y=0] and i = 10
During modifyPoint pt = java.awt.Point[x=5,y=5] and j = 15
after modifyPoint pt = java.awt.Point[x=5,y=5] and i = 10
实践2:对不变的date和objectreferences使用final
关键词final只能防止变量值的改变。如果被声明为final的变量是个object
reference,那么该reference不能被改变,必须永远指向同一个对象。然而
被指的那个对象可以随意改变。
class Circle {
private double rad;
public Circle(double r) {
rad = r;
}
public void setRad(double r) {
rad = r;
}
public double getRad(){
return rad;
}
}
public class FinalTest {
private static final Circle wheel = new Circle(5.0);
public static void main(String[] args) {
System.out.println("Radius of wheel is " + wheel.getRad());
wheel.setRad(7.5);
System.out.println("Radius of wheel now " + wheel.getRad());
// wheel = new Circle(8.0);
}
}
Radius of wheel is 5.0
Radius of wheel now 7.5
实践 3:缺省情况下所有non-static函数都可被覆写
class Base {
public void foo() {
}
public final void bar() {
}
}
public class Derived extends Base{
public void foo() {
//Overriding base.foo()
}
public void bar() {
//attempt to overriding base.bar()
}
}
实践 4:在 arrays和 Vectors之间慎重选择
相比于 array,当更多元素被加入 Vector以至于超出其容量时,其体积会动
态增长,这和 array有着显著的不同。此外, Vector在删除一些元素之后,
其所有[下标大于被删除元素]元素都依次前移,并获得(比原来小的)新下标。
实践 5:多态( polymorphism)优于 instanceof
Instanceof操作符很容易被误用。很多场合都应该以多态来替代instanceof。
无论何时当你看见instanceof出现,都请判断是否可以改进设计以消除它。
以这种方式来改进设计,会产生更合逻辑、更经得起推敲的设计,以及更
容易维护的代码。
interface Employee {
public int salary();
}
class Manager implements Employee {
private static final int mgrSal = 40000;
public int salary() {
return mgrSal;
}
}
class Programmer implements Employee {
private static final int proSal = 50000;
private static final int proBonus = 10000;
public int salary() {
return proSal;
}
public int bonus() {
return proBonus;
}
}
public class Payroll {
public int calcPayroll(Employee emp) {
int money = emp.salary();
if(emp instanceof Programmer) {
money += ((Programmer)emp).bonus();
}
return money;
}
public static void main(String[] args) {
Payroll pr = new Payroll();
Programmer prg = new Programmer();
Manager mgr = new Manager();
System.out.println("Payroll for Programmer is " + pr.calcPayroll(prg));
System.out.println("Payroll for Manager is " + pr.calcPayroll(mgr));
}
}
interface Employee {
public int salary();
public int bonus();
}
class Manager implements Employee {
private static final int mgrSal = 40000;
private static final int mgrBonus = 0;
public int salary() {
return mgrSal;
}
public int bonus() {
return mgrBonus;
}
}
class Programmer implements Employee {
private static final int proSal = 50000;
private static final int proBonus = 10000;
public int salary() {
return proSal;
}
public int bonus() {
return proBonus;
}
}
public class Payroll {
public int calcPayroll(Employee emp) {
return emp.salary() + emp.bonus();
}
public static void main(String[] args) {
Payroll pr = new Payroll();
Programmer prg = new Programmer();
Manager mgr = new Manager();
System.out.println("Payroll for Programmer is " + pr.calcPayroll(prg));
System.out.println("Payroll for Manager is " + pr.calcPayroll(mgr));
}
}
实践 6:必要时才使用instanceof
ScottMeyers在其著作《 EffectiveC++》条款39中表示,任何时候当你发现
自己写出如此形式的码: [如果对象的型别是T1,就做某件事,如果对象
的型别是T2,就做另一件事],请赏自己一个巴掌。大多数情形下Meyers
是正确的,他的贤明同样适用于Java。然而有你还是需要撰写这样风格的
代码。在这些极少数的场合里,你不必赏自己一个耳光。
无法将 referenceto Shape转型为 referenceto Integer,因为两个对象之
间没有任何关连。 Java编译器将检测出这一点,并发出编译错误消息。如
果你将referencetoShape转型为referencetoTriangle, 那么至少是在同一个
对象体系内进行,因此可能合法。但这种向下转型的合法性只在运行期才
被确认。Java运行期系统会检查shape1所把对象是否为一个Triangle对象。
由于它不是,遂产生ClassCastException异常。最后一个转型动作通过了上
述两项测试,因而合法。
class Shape1 {
}
class Circle1 extends Shape1 {
}
class Triangle1 extends Shape1 {
}
public class Shapes1 {
public static void main(String[] args) {
Shape1 shape1 = new Circle1();
Object shape2 = new Triangle1();
// Integer polynomial = new Integer(shape1); //Compile error
Triangle1 tr1 = (Triangle1)shape1; //Runtime error
Triangle1 tr2 = (Triangle1)shape2; //OK
}
}
这种场合下 instanceof操作符是必需的:
import java.util.Vector;
class Shape2 {
}
class Circle2 extends Shape2 {
public double radius() {
return 5.7;
}
}
class Triangle2 extends Shape2 {
public boolean isRightTriangle() {
return true;
}
}
public class StoreShapes {
public static void main(String[] args) {
Vector shapeVector = new Vector(3);
shapeVector.add(new Triangle2());
shapeVector.add(new Triangle2());
shapeVector.add(new Circle2());
int size = shapeVector.size();
for (int i = 0; i < size; i++) {
Object o = shapeVector.get(i);
if(o instanceof Triangle2) {
if(((Triangle2)o).isRightTriangle()) {
System.out.println("index " + i + " isRightTriangle is true");
}
}
else if (o instanceof Circle2) {
System.out.println("index " + i + "radius is " + ((Circle2)o).radius());
}
}
}
}
实践 7:一旦不再需要object references,就将它设为null
一旦你的程序不再参考(或说引用)某个对象,垃圾回收器就会回收这个
对象所拥有的内存。 当不再需要某对象时, 你可以将其references设为null,
以协助垃圾回收器取回内存。如果你的程序执行于一个内存受限环境中,
这可能很有益处。
即使垃圾回收器执行起来, 也并非所有[不再被引用](unreferenced)的内存都
可被回收。回收性能取决于你的代码所处之JVM( Java虚拟机)所采用的
垃圾回收算法。