五種方法創建 Java 對象,你知道幾種呢?

2022-01-22 程式設計師狗哥

來源 | 網絡

作為Java開發人員,我們通常每天都會創建許多對象,但是我們總是使用新的或依賴管理系統(例如Spring)來創建這些對象。但是,有更多方法可以創建本文中將要研究的對象。用Java創建對象的共有5種核心方式,下面將以其示例加以說明,然後介紹創建對象的行的字節碼。但是,有很多API可以為我們創建對象,但是這些API還將間接使用這5種核心方式之一,例如Spring BeanFactory。如果您將執行最後給出的程序,則會看到方法1、2、3使用構造函數創建對象,而4、5沒有調用構造函數創建對象。1、使用新關鍵字這是創建對象的最常見和常規的方法,也是一種非常簡單的方法。通過使用此方法,我們可以調用要調用的任何構造函數(無參數的構造函數和參數化的)。
Employee emp1 = new Employee();

2.使用Class類的newInstance()方法我們還可以使用Class類的newInstance()方法創建一個對象。此newInstance()方法調用no-arg構造函數來創建對象。我們可以通過newInstance()通過以下方式創建對象:
Employee emp2 = (Employee) Class.forName("org.programming.mitra.exercises.Employee").newInstance();

Employee emp2 = Employee.class.newInstance();

3.使用構造方法類的newInstance()方法與Class類的newInstance()方法類似,java.lang.reflect.Constructor類中有一個newInstance()方法可用於創建對象。我們還可以使用此newInstance()方法來調用參數化構造函數和私有構造函數。
Constructor<Employee> constructor = Employee.class.getConstructor();

Employee emp3 = constructor.newInstance();

這兩種newInstance()方法都被稱為創建對象的反射方式。實際上,Class類的newInstance()方法在內部使用了Constructor類的newInstance()方法。這就是為什麼最好使用後一種方法,並且也將其用於諸如Spring,Hibernate,Struts等不同框架的原因。要了解這兩種newInstance()方法之間的區別,請閱讀使用Example在Java中通過Reflection創建對象。4.使用clone()方法:每當我們在任何對象上調用clone()時,JVM實際上都會為我們創建一個新對象,並將先前對象的所有內容複製到其中。使用clone方法創建對象不會調用任何構造函數。要在對象上使用clone()方法,我們需要實現Cloneable並在其中定義clone()方法。
Employee emp4 = (Employee) emp3.clone();

Java克隆是Java社區中最值得探討的話題,它的確有其缺點,但是在對象完全滿足Java克隆的強制條件之前,它仍然是創建任何對象的副本的最流行和最簡單的方法。5.使用反序列化每當我們序列化然後反序列化一個對象時, JVM就會為我們創建一個單獨的對象。在反序列化中,JVM不使用任何構造函數來創建對象。要反序列化對象,我們需要在類中實現Serializable接口。
ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"));
Employee emp5 = (Employee) in.readObject();

正如我們在上面的字節碼中看到的那樣,所有四個方法調用都轉換為invokevirtual(這些方法直接處理對象的創建),除了第一個轉換為兩個調用的方法是一個是新的,另一個是調用特殊的(對構造函數的調用)。例:讓我們考慮一個我們要為其創建對象的Employee類:
class Employee implements Cloneable, Serializable {

    private static final long serialVersionUID = 1L;

    private String name;

    public Employee() { System.out.println("Employee Constructor Called..."); }

    public String getName() { return name; }

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Employee employee = (Employee) o;
        return Objects.equals(name, employee.name);
    }

    @Override
    public int hashCode() { return Objects.hash(name); }

    @Override
    public String toString() { return String.format("Employee{name='%s'}", name); }

    @Override
    public Object clone() {
        Object obj = null;
        try {
            obj = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return obj;
    }
}

在下面的Java程序中,我們將以所有5種方式創建Employee對象。
public class ObjectCreation {
    public static void main(String... args) throws Exception {

        // 1. Using new keyword
        Employee emp1 = new Employee();
        emp1.setName("emp1");


        // 2. Using Class class's newInstance() method
        Employee emp2 = Employee.class.newInstance();
        emp2.setName("emp2");


        // 3. Using Constructor class's newInstance() method
        Constructor<Employee> constructor = Employee.class.getConstructor();
        Employee emp3 = constructor.newInstance();
        emp3.setName("emp3");

        // 4. Using clone() method
        Employee emp4 = (Employee) emp3.clone();
        emp4.setName("emp4");


        // Serialization
        try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data.obj"))) {
            out.writeObject(emp4);
        }

        // 5. Using Deserialization
        Employee emp5;
        try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("data.obj"))) {
            emp5 = (Employee) in.readObject();
            emp5.setName("emp5");
        }

        System.out.println(emp1 + ", hashcode : " + emp1.hashCode());
        System.out.println(emp2 + ", hashcode : " + emp2.hashCode());
        System.out.println(emp3 + ", hashcode : " + emp3.hashCode());
        System.out.println(emp4 + ", hashcode : " + emp4.hashCode());
        System.out.println(emp5 + ", hashcode : " + emp5.hashCode());
    }
}

Employee Constructor Called...
Employee Constructor Called...
Employee Constructor Called...
Employee{name='emp1'}, hashcode : 3117192
Employee{name='emp2'}, hashcode : 3117193
Employee{name='emp3'}, hashcode : 3117194
Employee{name='emp4'}, hashcode : 3117195
Employee{name='emp5'}, hashcode : 3117196

或許你還想看

相關焦點

  • 五種方法創建java對象,你知道幾種呢?
    作為Java開發人員,我們通常每天都會創建許多對象,但是我們總是使用新的或依賴管理系統(例如Spring)來創建這些對象。但是,有更多方法可以創建本文中將要研究的對象。用Java創建對象的共有5種核心方式,下面將以其示例加以說明,然後介紹創建對象的行的字節碼。
  • Java中創建對象的5種方式
    然而這裡有很多創建對象的方法,我們會在這篇文章中學到。Java中有5種創建對象的方式,下面給出它們的例子還有它們的字節碼使用new關鍵字} → 調用了構造函數使用Class類的newInstance方法} → 調用了構造函數使用Constructor類的newInstance方法} → 調用了構造函數使用clone方法} → 沒有調用構造函數使用反序列化} → 沒有調用構造函數如果你運行了末尾的的程序,你會發現方法1,2,3
  • 用Java創建對象的5種不同方式
    作為Java開發人員,我們通常每天創建許多對象,但是我們始終使用依賴管理系統(例如Spring)來創建這些對象。但是,還有更多創建對象的方法,我們將在本文中進行研究。用Java創建對象的共有五種方法,下面將通過示例說明這些方法,然後介紹創建對象的行的字節碼。
  • java創建對象的過程詳解(從內存角度分析)
    先給出這篇文章的大致脈絡:首先,介紹一下java中對象的創建基本知識然後,介紹一下對象初始化的順序接下來,介紹一下創建對象的幾種方式最後,進行一個總結。小結:創建一個對象包含下面兩個過程:1、類構造器完成類初始化(分配內存、賦予默認值)2、類實例化(賦予給定值)二、類初始化下面我們直接給出一個例子看一下java是如何初始化的。我們知道一個類中,往往包含靜態變量、靜態代碼塊、變量、普通方法、構造方法等信息。那麼他們是如何初始化的呢?
  • Java 生成隨機數的 5 種方式,你知道幾種?
    Math.random() 靜態方法 產生的隨機數是 0 - 1 之間的一個 ,即 。 當第一次調用 方法時,自動創建了一個偽隨機數生成器,實際上用的是 。當接下來繼續調用 方法時,就會使用這個新的偽隨機數生成器。
  • java.util.Scanner的幾種next方法
    java.util.Scanner,這個類,想必大家都不怎麼陌生,在初學Java這門程式語言時,都見過,使用過吧。今天就來說說java.util.Scanner類的幾種next方法。scanner.nextInt()方法上面的兩個示例代碼都是獲取輸入的字符串,那如果是要獲取數值呢。看看下面的這段示例代碼。如上面示例所示,scanner.nextInt()的掃描結果會忽略前面的空格,輸入內容中遇到空格後,從空格開始往後的內容就都不作為掃描結果了。
  • EffectiveJava-1-創建和銷毀對象
    可以不用在每次調用時都創建一個新的對象,可以使用預先構建好的對象,或將構建好的對象緩存起來,進行重複利用,適用於經常請求創建相同對象,並且創建對象的代價很高,如常見的單例模式寫法就是對這一點的應用;實例受控的類:能為重複的調用返回相同的類,有助於類控制某個時刻哪些實例應該存在,功能如下:1.確保它是一個Singleton或者是不可實例化的;2.使得不可變的類不會存在兩個相等的實例
  • Java之創建多線程的第一種方式,thread類
    在java.long包下,有這樣一個類java.long.Thread類代表線程,所有的線程對象必須是Thread類或其子類的實例。每一個線程的作用是完成一定的任務,就是執行一段程序流即一段順序執行的代碼。Java中使用線程執行體來代表這段程序流。
  • @Pointcut 的 12 種用法,你知道幾種?
    表達式標籤(10種)execution:用於匹配方法執行的連接點within:用於匹配指定類型內的方法執行this:用於匹配當前AOP代理對象類型的執行方法;注意是AOP代理對象的類型匹配,這樣就可能包括引入接口也類型匹配target:用於匹配當前目標對象類型的執行方法;注意是目標對象的類型匹配,這樣就不包括引入接口也類型匹配
  • Java從零開始學 - 第31天:獲取線程執行結果,這6種方法你都知道?
    點擊上方關注 「Java研究所」設為「星標」,和你一起掌握更多資料庫知識這是java高並發系列第31篇。環境:jdk1.8。FutureTask對象,調用futureTask.get()會阻塞當前線程,子線程中休眠了3秒,然後調用futureTask.run();當futureTask的run()方法執行完畢之後,futureTask.get()會從阻塞中返回。
  • Java隨機數的幾種有趣用法
    ()使用一個內部的隨機生成對象– 一個很強大的對象可以靈活的隨機產生:布爾值、所有數字類型,甚至是高斯分布。例如:new java.util.Random().nextInt(10)  它有一個缺點,就是它是一個對象。它的方法必須是通過一個實例來調用,這意味著必須先調用它的構造函數。如果在內存充足的情況下,像上面的表達式是可以接受的;但內存不足時,就會帶來問題。  一個簡單的解決方案,可以避免每次需要生成一個隨機數時創建一個新實例,那就是使用一個靜態類。
  • Java字符串拼接的五種方法,哪種性能最好?
    大家好,我是D哥點擊關注下方公眾號,Java面試資料 都在這裡作者: 老壇酸菜WH來源 : cnblogs.com/twzheng/p/5923642.html> 字符串拼接一般使用「+」,但是「+」不能滿足大批量數據的處理,Java中有以下五種方法處理字符串拼接
  • 淺談Java中的幾種隨機數
    例如:new java.util.Random().nextInt(10) 它有一個缺點,就是它是一個對象。它的方法必須是通過一個實例來調用,這意味著必須先調用它的構造函數。如果在內存充足的情況下,像上面的表達式是可以接受的;但內存不足時,就會帶來問題。
  • java生成隨機數的五種方法
    當第一次調用 Math.random() 方法時,自動創建了一個偽隨機數生成器,實際上用的是 new java.util.Random()。當接下來繼續調用 Math.random() 方法時,就會使用這個新的偽隨機數生成器。
  • 幾種任務調度的 Java 實現方法與比較
    本文由淺入深介紹了幾種任務調度的 Java 實現方法,包括 Timer,Scheduler, Quartz 以及 JCron Tab,並對其優缺點進行比較,目的在於給需要開發任務調度的程式設計師提供有價值的參考。 前言 任務調度是指基於給定時間點,給定時間間隔或者給定執行次數自動執行任務。
  • 對象的創建過程
    我們使用main函數創建School的一個對象,那麼這個過程發生了哪些事情?在JVM內存中多了什麼呢?讓我們一起看下吧!對象創建的步驟對象的創建是在主線程的main()方法中,所以在主線程的虛擬機棧中就會創建main()的棧幀,main()就是當前方法。我們回顧下棧和棧幀。
  • 關於 Java 對象序列化您不知道的 5 件事
    因此,我們需要 serialVersionUID 欄位,它是通過對原始(或 V1)版本的 Person 類運行 JDK serialver命令計算出的。如果需要對整個對象進行加密和籤名,最簡單的是將它放在一個 javax.crypto.SealedObject 和/或 java.security.SignedObject 包裝器中。兩者都是可序列化的,所以將對象包裝在 SealedObject 中可以圍繞原對象創建一種 「包裝盒」。必須有對稱密鑰才能解密,而且密鑰必須單獨管理。
  • js創建對象的5種方式
    首先說說面向對象編程的特點:抽象:抓住核心問題封裝:只能通過對象來訪問方法繼承:從已有的對象下繼承出新的對象多態:多對象的不同形態創建對象的5種方式javascript 創建對象簡單的來說,無非就是使用內置對象或各種自定義對象,當然還可以使用JSON,但寫法有很多,也能混合使用。
  • js創建對象的幾種方式
    使用Object構造函數來創建一個對象,下面代碼創建了一個person對象,並用兩種方式列印出了Name的屬性值。使用工廠模式創建對象,返回帶有屬性和方法的person對象。組合使用原型模式和構造函數創建對象,解決了方法5中提到的缺陷,而且這也是使用最廣泛、認同度最高的創建對象的方法。
  • 你了解java中的幾種編碼方式?解決亂碼問題可能並不麻煩
    由於之前就知道String中的轉換方式,還有一些工具類,因此今天就好好的整理一下java中jdk提供的幾種轉換方式,希望對你有幫助。一、編碼轉換原理1、為什麼需要編碼我們知道計算機存儲信息的最小單位是一個字節8位,能夠表示256個字符。這對於早起的英文來說足夠了。即使是加上一些常見符號也足夠。