国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Java 創(chuàng)建對(duì)象的7種方式

這篇具有很好參考價(jià)值的文章主要介紹了Java 創(chuàng)建對(duì)象的7種方式。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

package com.xu.es.document.entity;

import lombok.Data;

import java.io.Serializable;

/**
 * @author itmei
 * @date 2023/5/25 21:48
 * @description: 學(xué)生類
 * @title: Student
 * @package com.xu.es.document.entity
 */
@Data
public class Student implements Cloneable, Serializable {

    public Student() {
    }

    public Student(int age) {
        this.age = age;
    }

    private String id;

    private int age;

    private String name;

    @Override
    public Student clone() {
        try {
            return (Student) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }

}

1 使用new關(guān)鍵字

這是最常見的創(chuàng)建對(duì)象的方式。使用 new 關(guān)鍵字,調(diào)用對(duì)象的構(gòu)造方法來創(chuàng)建一個(gè)新的實(shí)例。

package com.xu.es.document.entity;

import cn.hutool.json.JSONUtil;

/**
 * @author x
 * @date 2023/5/25 21:38
 * @description: Java 創(chuàng)建對(duì)象的方式
 * @title: Test
 * @package com.xu.es.document.entity
 */
public class Test {

    public static void main(String[] args) {
        Student object = new Student(10);
        System.out.println(JSONUtil.toJsonPrettyStr(object));
    }
}
{
    "age": 10
}

Process finished with exit code 0

2 使用Class類的newInstance()方法

Java中的每個(gè)類都有一個(gè)名為 Class 的類對(duì)象,可以使用它的 newInstance() 方法創(chuàng)建類的實(shí)例。這種方式要求類必須有一個(gè)無參的構(gòu)造方法。

package com.xu.es.document.entity;

import cn.hutool.json.JSONUtil;

/**
 * @author x
 * @date 2023/5/25 21:38
 * @description: Java 創(chuàng)建對(duì)象的方式
 * @title: Test
 * @package com.xu.es.document.entity
 */
public class Test {

    public static void main(String[] args) throws Exception {
        Student object = Student.class.getDeclaredConstructor().newInstance();
        System.out.println(JSONUtil.toJsonPrettyStr(object));
    }
}
{
    "age": 0
}

Process finished with exit code 0

3 使用Constructor類的newInstance()方法

Java的反射機(jī)制允許在運(yùn)行時(shí)動(dòng)態(tài)地獲取類的信息并操作類。通過 Class 類的 getConstructor() 和 newInstance() 方法可以創(chuàng)建對(duì)象。這種方式可以使用帶參的構(gòu)造方法。

package com.xu.es.document.entity;

import cn.hutool.json.JSONUtil;

/**
 * @author x
 * @date 2023/5/25 21:38
 * @description: Java 創(chuàng)建對(duì)象的方式
 * @title: Test
 * @package com.xu.es.document.entity
 */
public class Test {

    public static void main(String[] args) throws Exception {
        Class<?> clazz = Student.class;
        Student object = (Student) clazz.getDeclaredConstructor(int.class).newInstance(10);
        System.out.println(JSONUtil.toJsonPrettyStr(object));
    }
}
{
    "age": 10
}

Process finished with exit code 0

4 使用clone()方法

需要實(shí)現(xiàn)Cloneable,對(duì)象拷貝是創(chuàng)建對(duì)象的一種方式,它通過復(fù)制一個(gè)已有對(duì)象的值來創(chuàng)建一個(gè)新的對(duì)象。被拷貝的類需要實(shí)現(xiàn) Cloneable 接口,并重寫 clone() 方法,淺clone()不會(huì)調(diào)用構(gòu)造方法。

package com.xu.es.document.entity;

import cn.hutool.json.JSONUtil;

/**
 * @author x
 * @date 2023/5/25 21:38
 * @description: Java 創(chuàng)建對(duì)象的方式
 * @title: Test
 * @package com.xu.es.document.entity
 */
public class Test {

    public static void main(String[] args) {
        Student object = new Student(10);
        Student object1 = object.clone();
        System.out.println(JSONUtil.toJsonPrettyStr(object1));
    }
}
{
    "age": 10
}

Process finished with exit code 0

5 反序列化

需要實(shí)現(xiàn)Serializable,反序列化是將對(duì)象從字節(jié)流(如文件、網(wǎng)絡(luò)傳輸?shù)龋┺D(zhuǎn)換回內(nèi)存中的對(duì)象的過程。在進(jìn)行反序列化時(shí),Java會(huì)使用特定的機(jī)制創(chuàng)建對(duì)象,并將字節(jié)流中的數(shù)據(jù)填充到對(duì)象中。

反序列化創(chuàng)建對(duì)象的原理如下:

類加載:在進(jìn)行反序列化之前,Java需要加載類的定義。如果已加載的類與序列化數(shù)據(jù)中的類完全匹配,則直接使用已加載的類。否則,Java會(huì)嘗試根據(jù)序列化數(shù)據(jù)中的類名去加載類定義。

對(duì)象實(shí)例化:一旦類定義加載完成,Java使用類的構(gòu)造函數(shù)創(chuàng)建一個(gè)新的對(duì)象實(shí)例。通常情況下,會(huì)調(diào)用類的無參構(gòu)造函數(shù)來創(chuàng)建對(duì)象。如果類中沒有無參構(gòu)造函數(shù),或者無法訪問無參構(gòu)造函數(shù)(如私有構(gòu)造函數(shù)),則可能會(huì)導(dǎo)致反序列化失敗。

數(shù)據(jù)填充:在對(duì)象實(shí)例化后,Java將會(huì)將序列化數(shù)據(jù)中的字段值逐個(gè)填充到對(duì)象的對(duì)應(yīng)字段中。這個(gè)過程會(huì)使用反射來訪問對(duì)象的字段,并根據(jù)字段的類型和值進(jìn)行填充。

如果是文件可以使用FileInputStream和ByteArrayOutputStream的原理一樣。

package com.xu.es.document.entity;

import cn.hutool.json.JSONUtil;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * @author x
 * @date 2023/5/25 21:38
 * @description: Java 創(chuàng)建對(duì)象的方式
 * @title: Test
 * @package com.xu.es.document.entity
 */
public class Test {

    public static void main(String[] args) throws Exception {
        Student object = new Student(10);
        byte[] bytes = serialize(object);
        Student object1 = (Student) deserialize(bytes);
        System.out.println(JSONUtil.toJsonPrettyStr(object1));
    }

    private static byte[] serialize(Student object) throws Exception {
        ByteArrayOutputStream bOut = new ByteArrayOutputStream();
        ObjectOutputStream oOut = new ObjectOutputStream(bOut);
        oOut.writeObject(object);
        return bOut.toByteArray();
    }

    private static Object deserialize(byte[] object) throws Exception {
        ObjectInputStream oIn = new ObjectInputStream(new ByteArrayInputStream(object));
        return oIn.readObject();
    }

}
{
    "age": 10
}

Process finished with exit code 0

6 使用MethodHandles

Java MethodHandles是Java 7中引入的一種新的反射機(jī)制,它提供了對(duì)方法、字段和構(gòu)造函數(shù)的動(dòng)態(tài)訪問和調(diào)用。相比傳統(tǒng)的反射API,MethodHandles在性能和安全性方面都有所提升。

MethodHandles的原理可以簡要概括為以下幾個(gè)步驟:

獲取MethodHandle:首先,需要通過MethodHandles類的靜態(tài)方法來獲取MethodHandle對(duì)象。MethodHandle是一個(gè)對(duì)具體方法、字段或構(gòu)造函數(shù)的引用。

綁定方法接收者:MethodHandle對(duì)象是一個(gè)對(duì)方法的引用,但它并不包含方法所屬的對(duì)象實(shí)例。因此,在使用MethodHandle之前,需要通過bind方法將方法接收者(即調(diào)用方法的對(duì)象實(shí)例)綁定到MethodHandle上。

調(diào)用方法:一旦獲取到綁定了方法接收者的MethodHandle對(duì)象,就可以使用它來調(diào)用相應(yīng)的方法。MethodHandle提供了一系列invoke方法,用于根據(jù)方法的不同簽名進(jìn)行調(diào)用。

MethodHandles的工作原理是基于底層的字節(jié)碼指令,它直接操作方法、字段和構(gòu)造函數(shù)的字節(jié)碼,而不是通過反射API間接地調(diào)用它們。這使得MethodHandles比傳統(tǒng)的反射API更高效。

MethodHandles的性能優(yōu)勢(shì)主要體現(xiàn)在以下幾個(gè)方面:

內(nèi)聯(lián)優(yōu)化:MethodHandles在字節(jié)碼級(jí)別上進(jìn)行操作,可以進(jìn)行更好的內(nèi)聯(lián)優(yōu)化,減少方法調(diào)用的開銷。

類型檢查:MethodHandles在編譯時(shí)進(jìn)行類型檢查,而不是在運(yùn)行時(shí)。這使得類型錯(cuò)誤能夠在編譯時(shí)被發(fā)現(xiàn),而不是在運(yùn)行時(shí)拋出異常。

訪問權(quán)限檢查:MethodHandles可以直接訪問private方法、字段和構(gòu)造函數(shù),而不受訪問權(quán)限的限制。

適應(yīng)動(dòng)態(tài)語言:MethodHandles支持對(duì)動(dòng)態(tài)語言(如動(dòng)態(tài)類型語言)的調(diào)用,使得與傳統(tǒng)的反射API相比更加靈活。

package com.xu.es.document.entity;

import cn.hutool.json.JSONUtil;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;

/**
 * @author x
 * @date 2023/5/25 21:38
 * @description: Java 創(chuàng)建對(duì)象的方式
 * @title: Test
 * @package com.xu.es.document.entity
 */
public class Test {

    public static void main(String[] args) throws Throwable {
        MethodHandle handle = MethodHandles.lookup().findConstructor(Student.class, MethodType.methodType(void.class, int.class));
        Student student = (Student) handle.invoke(10);
        System.out.println(JSONUtil.toJsonPrettyStr(student));
    }

}

{
    "age": 10
}

Process finished with exit code 0

7 使用 Unfase

在 Java 中,Unsafe 是一個(gè)類提供了一些底層操作的方法,允許我們直接操縱內(nèi)存和執(zhí)行一些不安全的操作。Unsafe 類提供了訪問 Java 虛擬機(jī)底層操作的能力,包括直接操作內(nèi)存、執(zhí)行本地方法、加載類、分配實(shí)例等。

通過使用 Unsafe 類的方法之一,allocateInstance(Class cls),可以在不調(diào)用構(gòu)造函數(shù)的情況下創(chuàng)建對(duì)象。這是一種比較底層的操作,它會(huì)繞過類的構(gòu)造函數(shù),直接在內(nèi)存中分配對(duì)象的空間。

這個(gè)方法的實(shí)現(xiàn)原理如下:

首先,allocateInstance(Class cls) 方法會(huì)獲取傳入的類的類描述符(Class Descriptor),該描述符包含了類的結(jié)構(gòu)信息。

然后,Unsafe 類會(huì)根據(jù)類的描述符在堆中分配一塊內(nèi)存空間,這塊空間足夠存儲(chǔ)類的實(shí)例對(duì)象。

接下來,Unsafe 類會(huì)對(duì)這塊內(nèi)存空間進(jìn)行初始化,將其中的數(shù)據(jù)初始化為默認(rèn)值(對(duì)于基本類型,會(huì)初始化為 0 或者默認(rèn)值,對(duì)于引用類型,會(huì)初始化為 null)。

最后,allocateInstance(Class cls) 方法會(huì)返回這個(gè)內(nèi)存空間的引用作為結(jié)果,即創(chuàng)建了一個(gè)新的對(duì)象實(shí)例。

需要注意的是,使用 Unsafe 類創(chuàng)建對(duì)象是一種底層的操作,需要特別小心使用。因?yàn)樗鼤?huì)繞過構(gòu)造函數(shù),可能導(dǎo)致對(duì)象處于不一致的狀態(tài),或者執(zhí)行一些不安全的操作。這種方式一般用于某些特殊需求的場景,比如一些框架或庫的底層實(shí)現(xiàn)。對(duì)于普通的應(yīng)用開發(fā),一般不需要使用 Unsafe 類創(chuàng)建對(duì)象。文章來源地址http://www.zghlxwxcb.cn/news/detail-462010.html

package com.xu.es.document.entity;

import cn.hutool.json.JSONUtil;
import sun.misc.Unsafe;

import java.lang.reflect.Field;

/**
 * @author x
 * @date 2023/5/25 21:38
 * @description: Java 創(chuàng)建對(duì)象的方式
 * @title: Test
 * @package com.xu.es.document.entity
 */
public class Test {

    public static void main(String[] args) throws Throwable {
        Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
        unsafeField.setAccessible(true);
        Unsafe unsafe = (Unsafe) unsafeField.get(null);

        Student student = (Student) unsafe.allocateInstance(Student.class);
        System.out.println(JSONUtil.toJsonPrettyStr(student));
    }

}

到了這里,關(guān)于Java 創(chuàng)建對(duì)象的7種方式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • java import、package與php的namespace和use、requie實(shí)質(zhì)

    首先,java的工作原理是,首先去java的環(huán)境變量classpath或者你當(dāng)前編譯目錄下去找有沒有你需要的類 import、package 后跟著的其實(shí)不是文件的真實(shí)路徑,事實(shí)上,它們不需要按照名稱組織文件夾,你把他們統(tǒng)統(tǒng)放在一個(gè)目錄下也可以正常編譯運(yùn)行。將其按照文件路徑組織僅僅是

    2024年02月11日
    瀏覽(19)
  • Java進(jìn)階(1)——JVM的內(nèi)存分配 & 反射Class類的類對(duì)象 & 創(chuàng)建對(duì)象的幾種方式 & 類加載(何時(shí)進(jìn)入內(nèi)存JVM)& 注解 & 反射+注解的案例

    Java進(jìn)階(1)——JVM的內(nèi)存分配 & 反射Class類的類對(duì)象 & 創(chuàng)建對(duì)象的幾種方式 & 類加載(何時(shí)進(jìn)入內(nèi)存JVM)& 注解 & 反射+注解的案例

    1.java運(yùn)行時(shí)的內(nèi)存分配,創(chuàng)建對(duì)象時(shí)內(nèi)存分配; 2.類加載的順序,創(chuàng)建一個(gè)唯一的類的類對(duì)象; 3.創(chuàng)建對(duì)象的方式,new,Class.forName,clone; 4.什么時(shí)候加載.class文件進(jìn)入JVM內(nèi)存中,看到new,Class.forName; 5.如何加載?雙親委托(委派)機(jī)制:安全;AppClassLoader; 6.反射實(shí)質(zhì):能

    2024年02月14日
    瀏覽(32)
  • java 使用documents4j將XML轉(zhuǎn)為pdf文件的方式

    java 使用documents4j將XML轉(zhuǎn)為pdf文件的方式

    通過spire.doc.free將word轉(zhuǎn)換成PDF時(shí)存在缺陷:只能獲取前3頁。獲取全文另外需支付費(fèi)用。 使用documents4j,documents4j會(huì)保留原word文件中更多的樣式,如修訂模式下的差異化字體顏色、文檔右側(cè)修訂記錄等。 1.引入Pom 2.??xml2pdf方法如下,xmlpath是xml文件地址,pdfPath是生成的pdf地址

    2024年02月21日
    瀏覽(21)
  • Java進(jìn)階(4)——結(jié)合類加載JVM的過程理解創(chuàng)建對(duì)象的幾種方式:new,反射Class,克隆clone(拷貝),序列化反序列化

    Java進(jìn)階(4)——結(jié)合類加載JVM的過程理解創(chuàng)建對(duì)象的幾種方式:new,反射Class,克隆clone(拷貝),序列化反序列化

    1.類什么時(shí)候被加載到JVM中,new,Class.forName: Class.forName(“包名.類名”); 2.創(chuàng)建對(duì)象的方式,反射,本質(zhì)是獲得類的類對(duì)象Class; 3.克隆clone,深拷貝,淺拷貝的對(duì)比; 4.序列化和反序列化的方式; Hello h; // 此時(shí)沒有用Hello,jvm并沒有進(jìn)行類加載 看到new : new Book() Class.forName:

    2024年02月12日
    瀏覽(30)
  • java 將word轉(zhuǎn)為pdf文件的兩種方式【spire.doc.free】【documents4j】

    java 將word轉(zhuǎn)為pdf文件的兩種方式【spire.doc.free】【documents4j】

    如資產(chǎn)證明等場景下,一般要求同時(shí)生成word與pdf兩種格式的證明文件,且兩者格式需保持一致,可以各自單獨(dú)生成,但那樣可能需要維護(hù)兩個(gè)模板文件,所以也可以僅定義一份word的模板文件,使用模板生成word文件,再將word轉(zhuǎn)換為pdf,這樣不僅少維護(hù)一個(gè)模板,也可以保證

    2024年02月12日
    瀏覽(26)
  • 前端中對(duì)象的幾種創(chuàng)建方式

    前端中對(duì)象的幾種創(chuàng)建方式

    創(chuàng)建對(duì)象的幾種方式: 1.字面量方式 2.工廠模式 3.構(gòu)造函數(shù)模式 4.原型模式 缺點(diǎn):創(chuàng)建多個(gè)對(duì)象時(shí),需要重復(fù)代碼,不能復(fù)用。 作用:批量創(chuàng)建同類型對(duì)象,降低代碼冗余度。 缺點(diǎn):創(chuàng)建出的新對(duì)象,不知道是什么Person或者Animal類型,需看函數(shù)內(nèi)部代碼。 構(gòu)造函數(shù) 是一種特

    2023年04月08日
    瀏覽(17)
  • Spring IOC之對(duì)象的創(chuàng)建方式、策略及銷毀時(shí)機(jī)和生命周期且獲取方式

    Spring IOC之對(duì)象的創(chuàng)建方式、策略及銷毀時(shí)機(jī)和生命周期且獲取方式

    目錄 一、對(duì)象的創(chuàng)建方式 1. 使用構(gòu)造方法 2. 使用工廠類方法 3. 使用工廠類的靜態(tài)方法 二、對(duì)象的創(chuàng)建策略 1. 單例策略 2. 多例策略 三、對(duì)象的銷毀時(shí)機(jī) 四、生命周期方法 1. 定義生命周期方法 2. 配置生命周期方法 3. 測(cè)試 五、獲取Bean對(duì)象的方式 1. 通過id/name獲取 2. 通過類

    2024年02月01日
    瀏覽(14)
  • ImportError: Could not import docarray python package解決方案

    ImportError: Could not import docarray python package解決方案

    ??大家好,我是愛編程的喵喵。雙985碩士畢業(yè),現(xiàn)擔(dān)任全棧工程師一職,熱衷于將數(shù)據(jù)思維應(yīng)用到工作與生活中。從事機(jī)器學(xué)習(xí)以及相關(guān)的前后端開發(fā)工作。曾在阿里云、科大訊飛、CCF等比賽獲得多次Top名次。現(xiàn)為CSDN博客專家、人工智能領(lǐng)域優(yōu)質(zhì)創(chuàng)作者。喜歡通過博客創(chuàng)作

    2024年03月11日
    瀏覽(22)
  • ImportError: attempted relative import with no known parent package

    1.將source path 加入到sys目錄里 ?2.將相對(duì)導(dǎo)入改成直接導(dǎo)入,去掉 “.\\\"

    2024年01月19日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包