1. 程式人生 > >JAVA創建對象的五種方式

JAVA創建對象的五種方式

sta puts title turn serializa one specified args urn

最近在學習JAVA知識,通過網上翻看資料,發現原先有的理解不深的東西,漸漸明白了些。對象的使用,在編寫軟件過程中是必不可少的,不知道大家有沒和我一樣,幾乎都是使用new來創建。那麽,問題來了,JAVA有幾種創建對象 的方式呢?

  • 使用new關鍵字創建。
  • 使用Class的newInstance()方法,比如Person類,創建對象可以使用,但是下面的兩種方式不能調用private構造函數,且構造對象的類中必須包含無參構造函數,否則會報錯。
    public class person  {
        /**
         * 
         */
        private static final long serialVersionUID = 10L;
        String name 
    = "Jack"; public person(){ this.name = name + " ma"; System.out.println("construct Person"); } private person(int a,int b) { System.out.println("a:"+a+ " b:" + b); } @Override public String toString() { return name; } } 方法一
    //這裏的testReflect為包名,Person類在此包下 Class clazz = Class.forName("testReflect.person "); person p = (person ) clazz.newInstance(); 方法二 person p =person .class.newInstance();

  • 使用Constructor類的newInstance方法,此方法屬於反射,可以調用任何作用域的構造函數,private也可以,且創建對象的類構造函數可以任意。
    //調用無參構造函數 ,方式一
    person p = person.class.getDeclaredConstructor().newInstance();
    
    //調用無參構造函數 ,方式二 Constructor c1=person.class.getDeclaredConstructor(); c1.setAccessible(true); person p=(person)c1.newInstance();

    這裏大家思考下,在調用無參構造函數時,方式一和方式二有什麽區別? 大家應該看到了c1.setAccessible(true); 這句代碼吧,查看方法的定義包含如下:A value of true indicates that the reflected object should suppress Java language access checking when it is used,意思是為true的時候禁止驗證授權,換句話的理解就是,private的無參構造也可以調用。這就是方式一和方式二的區別,方式一若private作用域修飾,則會報錯。

    //調用有參構造函數
    Constructor c1=person.class.getDeclaredConstructor(new Class[] {int.class,int.class});
    或
    Constructor  c1=person.class.getDeclaredConstructor(int.class,int.class);
    • public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
                                            throws NoSuchMethodException,
                                                   SecurityException
      • Parameters:
        parameterTypes - the parameter array
        Returns:
        The Constructor object for the constructor with the specified parameter list
        傳入參數為數組。

  • 使用Clone的方法:無論何時我們調用一個對象的clone方法,JVM就會創建一個新的對象,將前面的對象的內容全部拷貝進去,用clone方法創建對象並不會調用任何構造函數。要使用clone方法,創建對象的類必須實現Cloneable接口並實現其定義的clone方法。關於clone可參考我轉載的JAVA深復制與淺復制。
  • 使用反序列化:當我們序列化和反序列化一個對象,JVM會給我們創建一個單獨的對象,在反序列化時,JVM創建對象並不會調用任何構造函數。為了反序列化一個對象,對應類需實現Serializable接口,附上一段具體實現代碼。
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.io.Serializable;
    public class People implements Serializable{
        private String name;
        public People(){
            this.name = "6點A君";
            System.out.println("construct people");
        }
        @Override
        public String toString() {
            return this.name;
        }
        
        public static void main(String[] args) {
            People p = new People();
            System.out.println(p);
            ObjectOutputStream oos = null;
            ObjectInputStream ois = null;
            try {
                FileOutputStream fos = new FileOutputStream("test.out");
                oos = new ObjectOutputStream(fos);
                oos.writeObject(p);
                oos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            People p1;
            try {
                FileInputStream fis = new FileInputStream("test.out");
                ois = new ObjectInputStream(fis);
                p1 = (People)ois.readObject();
                System.out.println(p1);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

JAVA創建對象的五種方式