最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java 序列化和Java反射的底層原理及區(qū)別對(duì)比分析

 更新時(shí)間:2025年12月01日 09:16:33   作者:Tan_Ying_Y  
Java 序列化和反射是 Java 中兩個(gè)不同維度的機(jī)制,序列化聚焦對(duì)象的持久化與傳輸,反射聚焦類 / 對(duì)象的動(dòng)態(tài)訪問(wèn)與操作,二者底層原理和應(yīng)用場(chǎng)景差異顯著,以下從底層原理、核心特性、區(qū)別對(duì)比展開解析,本文介紹Java 序列化和Java反射的底層原理及區(qū)別,感興趣的朋友一起看看吧

Java 序列化與反射:底層原理與核心區(qū)別

Java 序列化和反射是 Java 中兩個(gè)不同維度的機(jī)制,序列化聚焦對(duì)象的持久化與傳輸,反射聚焦類 / 對(duì)象的動(dòng)態(tài)訪問(wèn)與操作,二者底層原理和應(yīng)用場(chǎng)景差異顯著,以下從底層原理、核心特性、區(qū)別對(duì)比展開解析:

一、Java 序列化:底層原理與機(jī)制

1. 定義與核心目標(biāo)

序列化是將對(duì)象的狀態(tài)信息(屬性值)轉(zhuǎn)換為字節(jié)序列的過(guò)程,反序列化則是將字節(jié)序列恢復(fù)為對(duì)象的過(guò)程。核心目標(biāo)是實(shí)現(xiàn)對(duì)象的持久化(如存文件)、網(wǎng)絡(luò)傳輸(如 RPC 通信)或跨進(jìn)程共享。

2. 底層原理

(1)序列化的核心流程
  • 標(biāo)記可序列化:類需實(shí)現(xiàn)java.io.Serializable接口(標(biāo)記接口,無(wú)方法,僅標(biāo)識(shí)類可被序列化);
  • 對(duì)象狀態(tài)轉(zhuǎn)換:JVM 通過(guò)序列化機(jī)制遍歷對(duì)象的非靜態(tài)屬性(static、transient 修飾的屬性不序列化),將屬性值轉(zhuǎn)換為字節(jié)序列;
  • 處理引用關(guān)系:若對(duì)象引用其他可序列化對(duì)象,會(huì)遞歸序列化引用對(duì)象,通過(guò)serialVersionUID保證序列化與反序列化的類版本一致性。
(2)關(guān)鍵細(xì)節(jié)
  • serialVersionUID:類的版本號(hào),序列化時(shí)寫入字節(jié)序列,反序列化時(shí)校驗(yàn)版本號(hào)是否一致,不一致則拋出InvalidClassException
  • transient 關(guān)鍵字:修飾的屬性不參與序列化(如敏感數(shù)據(jù)、臨時(shí)狀態(tài));
  • 自定義序列化:通過(guò)重寫writeObject()/readObject()方法自定義序列化邏輯(如加密敏感屬性);
  • Externalizable 接口:替代Serializable,需手動(dòng)實(shí)現(xiàn)writeExternal()/readExternal(),完全控制序列化過(guò)程。
(3)底層實(shí)現(xiàn)(JVM 層面)

序列化由ObjectOutputStream實(shí)現(xiàn),底層通過(guò)反射獲取對(duì)象的類信息和屬性值,按特定格式(如魔數(shù)、版本號(hào)、類名、屬性類型 / 值)寫入字節(jié)流;反序列化由ObjectInputStream實(shí)現(xiàn),讀取字節(jié)流并反射創(chuàng)建對(duì)象、恢復(fù)屬性值。

3. 示例代碼

import java.io.*;
// 實(shí)現(xiàn)Serializable接口
class User implements Serializable {
    private static final long serialVersionUID = 1L; // 版本號(hào)
    private String name;
    private transient int age; // transient修飾,不序列化
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "User{name='" + name + "', age=" + age + "}";
    }
}
public class SerializationDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // 序列化:對(duì)象→字節(jié)序列(存文件)
        User user = new User("Alice", 20);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.ser"));
        oos.writeObject(user);
        oos.close();
        // 反序列化:字節(jié)序列→對(duì)象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.ser"));
        User deserializedUser = (User) ois.readObject();
        ois.close();
        System.out.println(deserializedUser); // 輸出:User{name='Alice', age=0}(age未序列化)
    }
}

二、Java 反射:底層原理與機(jī)制

1. 定義與核心目標(biāo)

反射是指程序在運(yùn)行時(shí)動(dòng)態(tài)獲取類的信息(如類名、屬性、方法),并動(dòng)態(tài)調(diào)用對(duì)象的方法、訪問(wèn)屬性的機(jī)制。核心目標(biāo)是打破封裝,實(shí)現(xiàn)對(duì)類 / 對(duì)象的動(dòng)態(tài)操作(如框架的靈活擴(kuò)展)。

2. 底層原理

(1)反射的核心基礎(chǔ)
  • Class 對(duì)象:每個(gè)類加載后,JVM 會(huì)為其創(chuàng)建一個(gè)Class對(duì)象(存儲(chǔ)類的元數(shù)據(jù):屬性、方法、構(gòu)造器等),反射通過(guò)Class對(duì)象訪問(wèn)類的信息;
  • 類加載機(jī)制:反射依賴類加載器(ClassLoader)加載類,可通過(guò)Class.forName()對(duì)象.getClass()、類名.class獲取Class對(duì)象。
(2)反射的核心流程
  • 獲取 Class 對(duì)象:通過(guò)三種方式獲取目標(biāo)類的Class實(shí)例;
  • 訪問(wèn)類成員:通過(guò)Class對(duì)象的方法(如getFields()、getMethods()getConstructors())獲取屬性、方法、構(gòu)造器的Field/Method/Constructor對(duì)象;
  • 動(dòng)態(tài)操作:通過(guò)Field.set()/get()訪問(wèn)屬性值,Method.invoke()調(diào)用方法,Constructor.newInstance()創(chuàng)建對(duì)象(可突破訪問(wèn)修飾符限制,如訪問(wèn) private 成員)。
(3)底層實(shí)現(xiàn)(JVM 層面)

JVM 在類加載時(shí)生成Class對(duì)象,存儲(chǔ)在方法區(qū)(元空間),反射通過(guò)本地方法(native)調(diào)用 JVM 的底層接口,直接訪問(wèn)Class對(duì)象的元數(shù)據(jù),繞過(guò)編譯期的訪問(wèn)檢查(如通過(guò)setAccessible(true)打破封裝)。

3. 示例代碼

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
class Person {
    private String name;
    private int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    private void sayHello() {
        System.out.println("Hello, " + name);
    }
}
public class ReflectionDemo {
    public static void main(String[] args) throws Exception {
        // 1. 獲取Class對(duì)象
        Class<?> personClass = Person.class;
        // 2. 通過(guò)反射創(chuàng)建對(duì)象(調(diào)用構(gòu)造器)
        Constructor<?> constructor = personClass.getConstructor(String.class, int.class);
        Object person = constructor.newInstance("Bob", 25);
        // 3. 訪問(wèn)private屬性
        Field nameField = personClass.getDeclaredField("name");
        nameField.setAccessible(true); // 打破封裝
        System.out.println("Name: " + nameField.get(person)); // 輸出:Name: Bob
        // 4. 調(diào)用private方法
        Method sayHelloMethod = personClass.getDeclaredMethod("sayHello");
        sayHelloMethod.setAccessible(true);
        sayHelloMethod.invoke(person); // 輸出:Hello, Bob
    }
}

三、序列化與反射的核心區(qū)別

維度Java 序列化Java 反射
核心目標(biāo)對(duì)象的持久化、傳輸(狀態(tài)保存與恢復(fù))運(yùn)行時(shí)動(dòng)態(tài)訪問(wèn) / 操作類 / 對(duì)象(打破封裝)
底層聚焦對(duì)象狀態(tài)的字節(jié)轉(zhuǎn)換類元數(shù)據(jù)的動(dòng)態(tài)訪問(wèn)
依賴機(jī)制實(shí)現(xiàn)Serializable接口,JVM 序列化規(guī)則依賴Class對(duì)象,反射 API(java.lang.reflect
操作對(duì)象對(duì)象的屬性值(非靜態(tài)、非 transient)類的屬性、方法、構(gòu)造器等成員
訪問(wèn)權(quán)限僅訪問(wèn)可序列化的屬性(受修飾符限制)可突破訪問(wèn)修飾符(setAccessible(true)
應(yīng)用場(chǎng)景分布式通信(RPC)、對(duì)象持久化(文件 / 數(shù)據(jù)庫(kù))框架開發(fā)(Spring/IOC、MyBatis)、動(dòng)態(tài)代理、工具類(如 JSON 解析)
性能開銷序列化 / 反序列化需遍歷對(duì)象引用,開銷中等反射需繞過(guò)編譯期檢查,性能低于直接調(diào)用(可通過(guò)緩存優(yōu)化)
版本兼容性依賴serialVersionUID保證版本一致無(wú)版本問(wèn)題,依賴類加載的元數(shù)據(jù)

四、關(guān)聯(lián)與總結(jié)

  • 關(guān)聯(lián):序列化底層依賴反射獲取對(duì)象的類信息和屬性值;反射可用于自定義序列化邏輯(如通過(guò)反射遍歷屬性實(shí)現(xiàn)自定義序列化)。
  • 核心區(qū)別:序列化是 “對(duì)象狀態(tài)的轉(zhuǎn)換與恢復(fù)”,反射是 “類 / 對(duì)象的動(dòng)態(tài)訪問(wèn)與操作”;序列化解決對(duì)象的傳輸與持久化問(wèn)題,反射解決程序的動(dòng)態(tài)性與靈活性問(wèn)題。

理解二者的關(guān)鍵在于:序列化關(guān)注對(duì)象的狀態(tài),反射關(guān)注類的結(jié)構(gòu),二者雖底層都依賴 JVM 的類元數(shù)據(jù),但目標(biāo)和應(yīng)用場(chǎng)景完全不同。

到此這篇關(guān)于Java 序列化和Java反射的底層原理以及區(qū)別?的文章就介紹到這了,更多相關(guān)java序列化和反射內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 如何獲取所有spring管理的bean

    如何獲取所有spring管理的bean

    這篇文章主要介紹了如何獲取所有spring管理的bean,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • SpringBoot整合Ehcache3的實(shí)現(xiàn)步驟

    SpringBoot整合Ehcache3的實(shí)現(xiàn)步驟

    本文主要介紹了SpringBoot整合Ehcache3的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Kotlin基礎(chǔ)教程之dataclass,objectclass,use函數(shù),類擴(kuò)展,socket

    Kotlin基礎(chǔ)教程之dataclass,objectclass,use函數(shù),類擴(kuò)展,socket

    這篇文章主要介紹了Kotlin基礎(chǔ)教程之dataclass,objectclass,use函數(shù),類擴(kuò)展,socket的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Java GC 機(jī)制與內(nèi)存分配策略詳解

    Java GC 機(jī)制與內(nèi)存分配策略詳解

    這篇文章主要介紹了Java GC 機(jī)制與內(nèi)存分配策略詳解的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • Mybatis-plus使用TableNameHandler分表詳解(附完整示例源碼)

    Mybatis-plus使用TableNameHandler分表詳解(附完整示例源碼)

    這篇文章主要介紹了Mybatis-plus使用TableNameHandler分表詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 深入剖析Spring如何解決循環(huán)依賴

    深入剖析Spring如何解決循環(huán)依賴

    循環(huán)依賴(Circular?Dependency)是指兩個(gè)或多個(gè)Bean相互依賴,形成一個(gè)閉環(huán)的情況,本文將和大家深入探討一下Spring如何解決循環(huán)依賴,需要的可以參考下
    2025-04-04
  • Java Predicate接口定義詳解

    Java Predicate接口定義詳解

    Predicate是Java中的一個(gè)函數(shù)式接口,它代表一個(gè)判斷邏輯,接收一個(gè)輸入?yún)?shù),返回一個(gè)布爾值,這篇文章主要介紹了Java Predicate接口的定義及示例代碼,需要的朋友可以參考下
    2025-04-04
  • java遍歷properties文件操作指南

    java遍歷properties文件操作指南

    在java項(xiàng)目開發(fā)過(guò)程中,使用properties文件作為配置基本上是必不可少的,有很多如系統(tǒng)配置信息,java如何遍歷properties文件呢,本文將詳細(xì)介紹,希望可以幫助到您
    2012-11-11
  • SpringBoot集成Neo4j的詳細(xì)教程

    SpringBoot集成Neo4j的詳細(xì)教程

    Spring Boot 提供了對(duì) Neo4j 的良好支持,使得開發(fā)者可以更方便地使用圖數(shù)據(jù)庫(kù),通過(guò)使用 Spring Data Neo4j,開發(fā)者可以輕松地進(jìn)行數(shù)據(jù)訪問(wèn)、操作以及管理,本文將詳細(xì)介紹如何在 Spring Boot 應(yīng)用中集成 Neo4j,需要的朋友可以參考下
    2024-11-11
  • 詳解如何自定義parallelStream線程池

    詳解如何自定義parallelStream線程池

    這篇文章主要為大家介紹了如何自定義parallelStream的線程池實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07

最新評(píng)論

乡城县| 封丘县| 东兴市| 广州市| 定陶县| 丰原市| 青浦区| 新田县| 横山县| 绥芬河市| 三穗县| 晋州市| 昆山市| 湛江市| 恭城| 明水县| 永顺县| 农安县| 东乡县| 邵阳县| 琼海市| 炎陵县| 长沙市| 金平| 延安市| 旺苍县| 淮南市| 穆棱市| 屏东市| 陆良县| 灵璧县| 博客| 深州市| 永年县| 阿合奇县| 伊吾县| 璧山县| 禹城市| 安泽县| 道真| 万全县|