天天看點

面試題Java對象建立的幾種方式對比總結,非常詳細的總結

作者:朝氣蓬勃的happycao

本章節講一下場景對象幾種方式,主要有new 、反射、克隆、反序列化

面試題Java對象建立的幾種方式對比總結,非常詳細的總結

new

這種方式是最常見的,通過調用構造方法建立對象,比如new String("hello"),這種方式一定知道具體要建立的類型,比如要建立String,就new String(); 并且不能是接口、抽象類。有人說不對呀,下面方式可以new 接口或者抽象類呀,其實這叫匿名類。在許多情況下,我們是不知道對象的具體類型的,如泛型 和 通用中間件

new Comparable<Integer>(){
            @Override
            public int compareTo(Integer o) {
                return 0;
            }
        };           
public class GenericBean <T>{
    
    public T newInstance(){
        // 編譯報錯
         return new T(); 
    }
    
}           

反射

調用Class.newInstance() 建立對象,這種方式一些架構很常見,如spring ,在spring boot 還 沒有流行之前,使用xml配置的方式,相信不會忘記經常需要配置某個類的全路徑。

這種方式有個限制必須要有預設的無參構造方法, 下面類代碼會抛異常 NoSuchMethodException: com.happycao.study.object.Student.<init>(),那些添加了帶參數的構造方法,而沒有提供無參的構造方法同學注意了。

public class Student {

    private String name ;
    private int age;
    
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {
        Class<Student> clazz = Student.class;
        try {
            clazz.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}           
面試題Java對象建立的幾種方式對比總結,非常詳細的總結

克隆

克隆需要實作Cloneable接口(可以試下沒有實作會抛異常),克隆對象與原對象不是同一個對象,克隆有淺拷貝、和深拷貝

淺拷貝修改對象屬性會影響原對象

深拷貝則不會, 深拷貝實作方式記住口訣,屬性也進行clone 。

面試題Java對象建立的幾種方式對比總結,非常詳細的總結
面試題Java對象建立的幾種方式對比總結,非常詳細的總結

這裡隻貼下深拷貝代碼

public class CloneBean  implements Cloneable {

    private int[] arr;

    public CloneBean( int[] arr) {

        this.arr = arr;
    }

    public void setArr(int[] arr) {
        this.arr = arr;
    }

    @Override
    protected CloneBean clone() throws CloneNotSupportedException {
        CloneBean cloneBean =  (CloneBean)super.clone();
        cloneBean.setArr(arr.clone());
        return cloneBean;
    }

    @Override
    public String toString() {
        return "CloneBean{" +
                ", arr=" + Arrays.toString(arr) +
                '}';
    }

    public static void main(String[] args) throws CloneNotSupportedException {
        int arr[] = new int[]{1,2,3};
        CloneBean cloneBean1 = new CloneBean(arr);
        CloneBean cloneBean2 = cloneBean1.clone();

        System.out.println(cloneBean2  == cloneBean1);
        System.out.println("cloneBean1" + cloneBean1);
        System.out.println("cloneBean2" + cloneBean2);

        arr[1] = 1000;
        System.out.println("cloneBean1" + cloneBean1);
        System.out.println("cloneBean2" + cloneBean2);
    }
}
           
面試題Java對象建立的幾種方式對比總結,非常詳細的總結

反序列化

對象序列化需要實作Serializable接口,序列化是 ObjectOutputStream.writeObject() 反序列化ObjectInputStream.writeObject 。在網絡傳輸中比較常見,筆者在大學一個大作業網絡白闆中第一次接觸

public class ExampleBean implements Serializable {

    private String name ;

    public ExampleBean(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "ExampleBean{" +
                "name='" + name + '\'' +
                '}';
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {

        ExampleBean exampleBean = new ExampleBean("hello");

        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(byteOut);
        out.writeObject(exampleBean);
        out.close();

        ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(byteOut.toByteArray()));
        ExampleBean exampleBean2 =  (ExampleBean)in.readObject();
        in.close();

        System.out.println(exampleBean2);
    }
}
           

還有沒有其他建立對象的方式,歡迎交流

繼續閱讀