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

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

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

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

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

一、Java 序列化:底層原理與機制

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

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

2. 底層原理

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

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

3. 示例代碼

import java.io.*;
// 實現(xiàn)Serializable接口
class User implements Serializable {
    private static final long serialVersionUID = 1L; // 版本號
    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 {
        // 序列化:對象→字節(jié)序列(存文件)
        User user = new User("Alice", 20);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.ser"));
        oos.writeObject(user);
        oos.close();
        // 反序列化:字節(jié)序列→對象
        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 反射:底層原理與機制

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

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

2. 底層原理

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

JVM 在類加載時生成Class對象,存儲在方法區(qū)(元空間),反射通過本地方法(native)調(diào)用 JVM 的底層接口,直接訪問Class對象的元數(shù)據(jù),繞過編譯期的訪問檢查(如通過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對象
        Class<?> personClass = Person.class;
        // 2. 通過反射創(chuàng)建對象(調(diào)用構(gòu)造器)
        Constructor<?> constructor = personClass.getConstructor(String.class, int.class);
        Object person = constructor.newInstance("Bob", 25);
        // 3. 訪問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)對象的持久化、傳輸(狀態(tài)保存與恢復(fù))運行時動態(tài)訪問 / 操作類 / 對象(打破封裝)
底層聚焦對象狀態(tài)的字節(jié)轉(zhuǎn)換類元數(shù)據(jù)的動態(tài)訪問
依賴機制實現(xiàn)Serializable接口,JVM 序列化規(guī)則依賴Class對象,反射 API(java.lang.reflect
操作對象對象的屬性值(非靜態(tài)、非 transient)類的屬性、方法、構(gòu)造器等成員
訪問權(quán)限僅訪問可序列化的屬性(受修飾符限制)可突破訪問修飾符(setAccessible(true)
應(yīng)用場景分布式通信(RPC)、對象持久化(文件 / 數(shù)據(jù)庫)框架開發(fā)(Spring/IOC、MyBatis)、動態(tài)代理、工具類(如 JSON 解析)
性能開銷序列化 / 反序列化需遍歷對象引用,開銷中等反射需繞過編譯期檢查,性能低于直接調(diào)用(可通過緩存優(yōu)化)
版本兼容性依賴serialVersionUID保證版本一致無版本問題,依賴類加載的元數(shù)據(jù)

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

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

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

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

相關(guān)文章

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

    如何獲取所有spring管理的bean

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

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

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

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

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

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

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

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

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

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

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

    Java Predicate接口定義詳解

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

    java遍歷properties文件操作指南

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

    SpringBoot集成Neo4j的詳細教程

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

    詳解如何自定義parallelStream線程池

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

最新評論

丹江口市| 保亭| 藁城市| 廊坊市| 博爱县| 张家界市| 平塘县| 奇台县| 荃湾区| 大厂| 湄潭县| 五华县| 马鞍山市| 奉贤区| 读书| 双江| 临桂县| 江源县| 潼关县| 会理县| 保德县| 宣汉县| 桃园县| 东源县| 叶城县| 山东省| 淳安县| 西昌市| 秦皇岛市| 嘉义市| 辽宁省| 济南市| 八宿县| 临城县| 青川县| 丽江市| 乌兰察布市| 客服| 太谷县| 遂川县| 丹巴县|