Another method get instance of JAVA Object

来源:互联网 发布:破解八零网络验证 编辑:程序博客网 时间:2024/05/07 16:00

构造器的陷阱

构造器是有返回值的,构造器返回它初始化的Java对象(new调用构造器就可看到构造器的返回值)。也就是说,构造器的返回值类型总是当前类。

构造器不能声明返回值类型,也不能使用void声明构造器没有返回值。

当为构造器声明添加任何返回值类型声明,或者添加void声明该构造器没有返回值时,编译器并不会提示这个构造器有错误,只是系统会把这个所谓的构造器当成普通方法处理。

构造器并不会创建Java对象,构造器只是负责执行初始化,在构造器执行之前,Java对象所需要的内存空间,应该说是由new关键字申请出来的。绝大部分时候,程序使用new关键字为一个Java对象申请空间之后,都需要使用构造器为这个对象执行初始化。但在某些时候,程序创建Java对象无需调用构造器,以下两种方式创建的Java对性爱那个无需使用构造器:

使用反序列化的方式恢复Java对象;

使用clone方法复制Java对象。

反序列化方法:

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

 

classWolfimplements java.io.Serializable{

       private Stringname;

       public Wolf(String name){

             System.out.println("Constuctor");

             this.name = name;

       }

       publicboolean equals(Object obj){

             if(this == obj){

                   returntrue;

             }

             if(obj.getClass() == Wolf.class){

                   Wolf target = (Wolf)obj;

                   return target.name.equals(this.name);

             }

             returnfalse;

       }

       publicint hashCode(){

             returnname.hashCode();

       }

}

publicclass Serializable {

     publicstaticvoid main(String[] args){

       Wolf w = new Wolf("wolf");

       Wolf w2 = null;

       ObjectOutputStream oos = null;

       ObjectInputStream ois = null;

       try{

             oos = new ObjectOutputStream(new FileOutputStream("a.bin"));

             ois = new ObjectInputStream(new FileInputStream("a.bin"));

             oos.writeObject(w);

             oos.flush();w2 = (Wolf)ois.readObject();

             System.out.println(w.equals(w2));

             System.out.println(w == w2);

       } catch (FileNotFoundException e) {

                  //TODO Auto-generated catch block

                  e.printStackTrace();

            } catch (IOException e) {

                  //TODO Auto-generated catch block

                  e.printStackTrace();

            } catch (ClassNotFoundException e) {

                  //TODO Auto-generated catch block

                  e.printStackTrace();

            }finally{

             if(oos!=null){

                   try {

                              oos.close();

                        } catch (IOException e) {

                              //TODO Auto-generated catch block

                              e.printStackTrace();

                        }

             }

             if(ois!=null){

                   try {

                              ois.close();

                        } catch (IOException e) {

                              //TODO Auto-generated catch block

                              e.printStackTrace();

                        }

             }

       }

     }

}

Output:

Constuctor

true

false

当创建Wolf对象时,程序调用了相应的构造器来对该对象执行初始化;当程序通过饭序列化机制恢复Java对象时,系统无需再调用构造器来执行初始化。

通过反序列化恢复出来的Wolf对象当然和原来的Wolf对象具有完全相同的实例变量值,但系统中将会产生两个Wolf对象。

如果想让序列化时也不会产生多个实例,应该这样写:

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.io.ObjectStreamException;

 

classSingletonimplements java.io.Serializable{

      privatestatic Singletoninstance;

      private Stringname;

      private Singleton(String name){

            System.out.println("Constructor");

            this.name = name;

      }

      publicstatic Singleton getInstance(String name){

            if(instance ==null){

                  instance =new Singleton(name);

            }

            returninstance;

      }

      private Object readResolve()throws ObjectStreamException

    {

            returninstance;

    }

}

publicclass SingletonTest {

    publicstaticvoid main(String[] args){

     Singleton s = Singleton.getInstance("Wolf");

       Singleton s2 = null;

       ObjectOutputStream oos = null;

       ObjectInputStream ois = null;

       try{

             oos = new ObjectOutputStream(new FileOutputStream("a.bin"));

             ois = new ObjectInputStream(new FileInputStream("a.bin"));

             oos.writeObject(s);

             oos.flush();

             s2 = (Singleton)ois.readObject();

             System.out.println(s ==s2);

       } catch (FileNotFoundException e) {

                  //TODO Auto-generated catch block

                  e.printStackTrace();

            } catch (IOException e) {

                  //TODO Auto-generated catch block

                  e.printStackTrace();

            } catch (ClassNotFoundException e) {

                  //TODO Auto-generated catch block

                  e.printStackTrace();

            }finally{

             if(oos!=null){

                   try {

                              oos.close();

                        } catch (IOException e) {

                              //TODO Auto-generated catch block

                              e.printStackTrace();

                        }

             }

             if(ois!=null){

                   try {

                              ois.close();

                        } catch (IOException e) {

                              //TODO Auto-generated catch block

                              e.printStackTrace();

                        }

             }

       }

    }

}

Output:

Constructor

True

JVM反序列化地恢复一个新对象时,系统会自动调用这个readReslove()方法返回制定好的对象,从而保证系统通过反序列化机制不会产生多个Java对象。

除了可以反序列化机制恢复Java对象无需构造器之外,使用clone()方法复制Java对象也无需调用构造器。如果希望某个Java类的实例是可复制的,对该Java类有如下两个要求。

让该Java类实现Cloneable接口;

为该Java类提供clone()方法,该方法负责进行复制。

class Dog implements Cloneable{
private String name;
private double weight;
public Dog(String name,double weight){
System.out.println("Dog Class Constructor");
this.name = name;
this.weight = weight;
}
public Object clone(){
Dog dog = null;
try{
dog = (Dog)super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return dog;
}
public boolean equals(Object obj){
if(this == obj){
return true;
}
if(obj.getClass() == Dog.class){
Dog target =(Dog)obj;
return target.name.equals(this.name) && target.weight == this.weight;
}
return false;
}
}
public class CloneTest {
    public static void main(String[] args){
    Dog dog = new Dog("Blot",9.8);
    Dog dog2 = (Dog)dog.clone();
    System.out.println(dog.equals(dog2));
    System.out.println(dog==dog2);
    }
}

output:

Dog Class Constructor
true
false

原创粉丝点击