Java建立對象的5種方式


Java中建立對象的5種方式

1.使用new關鍵字

package com.zmy.java.object;

public class Student{
    private String name;
    private Integer age;

    public Student() {
        System.out.println("無參構造方法!");
    }

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
        System.out.println("有參構造方法!");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    
    public static void main(String[] args) {
        /* 方式一,經過new關鍵字建立對象 */
        Student student = new Student();
        student.setName("小明");
        student.setAge(15);
        System.out.println(student.toString());
        }
}java

代碼執行結果:image-20200521213318544image-20200521213318544.png

執行結果分析:ide

經過new關鍵字建立對象時,會經過調用該類的無參構造方法或有參構造方法來建立一個對象實例。函數

2.使用clone()方法

經過其餘對象的clone()來生成新對象

package com.zmy.java.object;

/**
* 使用clone()方法,須要實現Cloneable接口和重寫Object類的clone()方法
*/
public class Student implements Cloneable{
    private String name;
    private Integer age;

    public Student() {
        System.out.println("無參構造方法!");
    }

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
        System.out.println("有參構造方法!");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

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

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }


    public static void main(String[] args) throws CloneNotSupportedException{
        Student student = new Student();
        student.setName("小明");
        student.setAge(15);        
this

       Student student2 = (Student) student.clone();
        System.out.println(student2);
        
        student2.setAge(14);
        student2.setName("小華");
        System.out.println(student2);
    }
spa

}orm

代碼執行結果
對象

1.png

執行結果分析:blog

使用clone()方法來建立對象B時,前提是已建立有對象A,而後經過調用對象A的clone()方法來賦值給對象B,此時對象B中的成員變量值均與對象A中的成員變量值同樣。接口

執行的順序是:ci

  1. 先建立對象A,並給對象A的成員變量賦值;

  2. 調用對象A的clone()方法,JVM會建立一個新對象B,並將對象A中的內容所有拷貝一份給對象B。

    注意:經過clone()建立對象時不會調用任何構造方法。


3.使用Class類的newInstance()方法

package com.zmy.java.object;

public class Student{
    private String name;
    private Integer age;

    public Student() {
        System.out.println("無參構造方法!");
    }

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
        System.out.println("有參構造方法!");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

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

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        Student student = (Student)Class.forName("com.zmy.java.object.Student").newInstance();
        student.setName("小明");
        student.setAge(15);
        System.out.println(student);



    }
}

代碼執行結果

3.png

執行結果分析:

經過Class.forName("該類的類路徑").newInstance()來建立對象時,會調用無參構造方法來建立一個對象。


4.使用Constructor的newInstance()方法

package com.zmy.java.object;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Student{
    private String name;
    private Integer age;

    private Student() {
        System.out.println("無參構造方法!");
    }

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
        System.out.println("有參構造方法!");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

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

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, CloneNotSupportedException, NoSuchMethodException, InvocationTargetException {

        Constructor constructor = Student.class.getDeclaredConstructor();
        Student student = (Student)constructor.newInstance();

        student.setName("小明");
        student.setAge(18);

        System.out.println(student);
    }
}

代碼執行結果:

4.png

執行結果分析:

經過Constructor的newInstance()方法來建立對象時,會經過調用無參構造方法或有參構造方法來建立對象。

注意本代碼實例中無參構造方法爲private類型!!!

注意:類名.class.getDeclaredConstructor()和類名.class.getConstructor()的區別!!!

getDeclaredConstructor:返回指定參數類型、全部聲明的(包括private)構造函數

getConstructor**:返回指定參數類型、具備public訪問權限的構造函數


5.使用反序列化

package com.zmy.java.object;

import java.io.*;

public class Student implements Serializable {
    private String name;
    private Integer age;

    public Student() {
        System.out.println("無參構造方法!");
    }

    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
        System.out.println("有參構造方法!");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

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

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

        Student student = new Student("小明",18);

        System.out.println("java序列化開始");
        // 文件輸出流
        FileOutputStream fos = new FileOutputStream("E:\\IdeaProjects\\project01\\src\\com\\zmy\\java\\object\\Student.ser");
        // 對象輸出流
        ObjectOutputStream oos = new ObjectOutputStream(fos);

        oos.writeObject(student);
        oos.close();
        fos.close();

        System.out.println("-----------------------------------------------------");

        System.out.println("java反序列化開始");
        // 文件輸入流
        FileInputStream fis = new FileInputStream("E:\\IdeaProjects\\project01\\src\\com\\zmy\\java\\object\\Student.ser");
        // 對象輸入流
        ObjectInputStream ois = new ObjectInputStream(fis);
        Student student1 = (Student) ois.readObject();
        System.out.println(student1);

    }
}
代碼執行結果分析:

5.png

執行結果分析:

Student類實現了Serializable接口後才能夠被序列化!編譯器先將代碼序列化到文件中,java默認序列化後的文件後綴爲.ser。而後,反序列化操做後獲得Student對象。

反序列化時並不會調用Student類的無參或有參構造方法!

   若是不想實例化對象的某個成員變量,能夠在成員變量前使用transient關鍵字!則該字段不會被序列化!

示例:

        public class Student implements Serializable {
        private String name;
        private transient Integer age;

    對於 JVM 能夠反序列化對象,它必須是可以找到字節碼的類。若是JVM在反序列化對象的過程當中找不到該類,則拋出一個 ClassNotFoundException 異常。

   注意,readObject() 方法的返回值被轉化成 Student引用。

相關文章
相關標籤/搜索