《改善java代码》第三章:关于类、对象、方法的java代码优化
- 实例化顺序:子类实例化时,会首先初始化父类,也就是初始化父类的变量,调用父类的构造函数,然后才会初始化子类的变量,调用子类自己的构造函数,最后生成一个实例对象。 因此要做到构造函数尽量简化,要达到一眼洞穿的境界。
- 不要在构造函数中初始化其他类,容易造成栈内存溢出。
- 让工具类不可实例化:将构造函数为private访问权限,除了类本身外,谁都不能产生一个实例。
- 代码的拷贝: Student stu1=new Student() ; Student stu2=stu1; 这里的stu1与stu2引用的是同一个对象。
如果对象实现了接口Cloneable,则对象具有了拷贝的功能,拷贝是在内存中进行的,所以性能方面比直接通过new一个对象要快得多。
public class Child implements Cloneable{ String name ; String sex; Father father; public Child(String name, Father father) { this.name = name; this.father = father; } @Override public String toString() { return "Child{" + "name='" + name + '\'' + ", sex='" + sex + '\'' + ", father=" + father.getName() + '}'; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
public class Father { String name; }
public class test { public static void main(String[] args) { Father father =new Father(); father.setName("父亲"); Child b=new Child("yhq",father); b.sex="女"; Child c=b; Child d=null; try { d= (Child) b.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } b.getFather().setName("干爹"); b.setName("wxh"); b.setSex("男"); System.out.println(b); System.out.println(c); System.out.println(d); } }
可以看到运行结果是下图。这就说明一个问题:对象拷贝有一个容易忽略的问题,即对象的浅拷贝。浅拷贝存在对象属性拷贝不彻底的问题。super.clone 是有缺陷的,它的拷贝规则是:基本类型(拷贝其值),对象(拷贝其引用),字符串(拷贝的是一个地址,是一个引用,但是在修改时,它会从字符串池中重新生成新的字符串,原有的字符串对象保持不变)
- 对象的拷贝最优解:推荐使用序列化实现对象的拷贝。
把对象写到流里的过程是序列化过程(Serialization),而把对象从流中读出来的过程则叫做反序列化过程(Deserialization)。
代码:https://gitee.com/yaohuiqin/codeimprove/tree/master/src/per/yhq/objectimprove/copyobject - 判断对象是否相等:
代码:https://gitee.com/yaohuiqin/codeimprove/tree/master/src/per/yhq/objectimprove/equalobject
包括:写equas()必须覆写hashCode() ,判断对象是否相等时,覆写equals方法判断对象类型时,不用instanceof 推荐使用class比较 , equals() 要考虑空指针 - 不要主动进行垃圾回收:
System.gc不要调用。 System.gc 要停止所有的响应,才能检查内存是否有可回收的对象,这对一个系统来说风险极大,将会严重影响业务的正常运行。