以下有两种方式创建Java对象无需使用构造器:
-使用反序列化的方式恢复Java对象。
-使用clone的方式复制Java对象。
class Wolf implements Serializable{
private String name;
Wolf(String name) {
System.out.println("调用");
this.name = name;
}
@Override
public boolean equals(Object obj) {
if(this == obj)
return true;
if(obj.getClass() == Wolf.class){
Wolf tar = (Wolf)obj;
return tar.name.equals(this.name);
}
return false;
}
@Override
public int hashCode() {
return name.hashCode();
}
}
public class SerializableTest {
public static void main(String[] args) throws Exception {
Wolf w = new Wolf("ABC");
System.out.println("ABC创建完成");
Wolf w2 = null;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("b.bin"));
ois = new ObjectInputStream(new FileInputStream("b.bin"));
//序列化输出Java对象
oos.writeObject(w);
oos.flush();
//反序列化恢复Java对象
w2 = (Wolf)ois.readObject();
System.out.println(w.equals(w2));
System.out.println(w == w2);
}
finally{
if(oos != null)
oos.close();
if(ois != null)
ois.close();
}
}
}
结果是:
调用
ABC创建完成
true
false
可见--恢复Java对象时无需调用它的构造器执行初始化。
通过反序列化恢复出来的Wolf对象当然和原来的对象拥有完全相同的实例变量,但系统将会产生两个Wolf对象。
当然这种反序列机制会破坏单例规则,如果要保障反序列化时也不会产生多个Java实例,则应该为单例类提供readResolve()方法,保障反序列化时只得到已有的Java实例
class Wolf implements Serializable{
private static Wolf instance;
private String name;
private Wolf(String name) {
System.out.println("调用");
this.name = name;
}
public static Wolf getInstance(String name){
if(instance == null)
instance = new Wolf(name);
return instance;
}
private Object readResolve(){
System.out.println("ddddd");
return instance;
}
@Override
public boolean equals(Object obj) {
if(this == obj)
return true;
if(obj.getClass() == Wolf.class){
Wolf tar = (Wolf)obj;
return tar.name.equals(this.name);
}
return false;
}
@Override
public int hashCode() {
return name.hashCode();
}
}
public class SerializableTest {
public static void main(String[] args) throws Exception {
Wolf w = Wolf.getInstance("ABC");
System.out.println("ABC创建完成");
Wolf w2 = null;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("b.bin"));
ois = new ObjectInputStream(new FileInputStream("b.bin"));
//序列化输出Java对象
oos.writeObject(w);
oos.flush();
//反序列化恢复Java对象
w2 = (Wolf)ois.readObject();
System.out.println(w.equals(w2));
System.out.println(w == w2);
}
finally{
if(oos != null)
oos.close();
if(ois != null)
ois.close();
}
}
}
JVM反序列恢复一个新对象时,会自动调用这个readResolve()方法返回指定好的对象。
clone 方法
class Dog implements Cloneable {
private String name;
public Dog(String name) {
System.out.println("调用DOg构造函数");
this.name = name;
}
@Override
public Object clone() {
Dog dog = null;
try {
dog = (Dog) super.clone();
} catch (CloneNotSupportedException e) {
}
return dog;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj.getClass() == Dog.class) {
Dog tarDog = (Dog) obj;
return tarDog.name.equals(this.name);
}
return false;
}
}
public class TestClone {
public static void main(String[] args) {
Dog dog = new Dog("xiaogou");
Dog s = (Dog) dog.clone();
System.out.println(dog.equals(s));
System.out.println(dog == s);
}
}
输出为:
调用DOg构造函数
true
false
可见clone方法并不调用构造器来创建对象