亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

首頁 Java java教程 掌握 Java 字節(jié)碼:使用 ASM 庫增強應(yīng)用程序的功能

掌握 Java 字節(jié)碼:使用 ASM 庫增強應(yīng)用程序的功能

Nov 24, 2024 am 11:28 AM

Mastering Java Bytecode: Boost Your App

Java 字節(jié)碼操作是一項強大的技術(shù),允許我們在運行時修改 Java 類。借助ASM庫,我們可以讀取、分析和轉(zhuǎn)換類文件,而無需原始源代碼。這為增強和優(yōu)化 Java 應(yīng)用程序開辟了一個充滿可能性的世界。

讓我們從探索字節(jié)碼操作的基礎(chǔ)知識開始。從本質(zhì)上講,Java 字節(jié)碼是編譯后的 Java 代碼的低級表示。這是 Java 虛擬機 (JVM) 實際執(zhí)行的內(nèi)容。通過操縱這個字節(jié)碼,我們可以在不接觸源代碼的情況下改變程序的行為方式。

ASM 庫提供了一組處理字節(jié)碼的工具。它輕量、快速并且廣泛應(yīng)用于 Java 生態(tài)系統(tǒng)中。首先,我們需要將 ASM 依賴項添加到我們的項目中。以下是我們?nèi)绾问褂?Maven 來做到這一點:

<dependency>
    <groupId>org.ow2.asm</groupId>
    <artifactId>asm</artifactId>
    <version>9.2</version>
</dependency>

現(xiàn)在我們已經(jīng)設(shè)置了 ASM,讓我們深入研究一些實際示例。字節(jié)碼操作的一種常見用例是向方法添加日志記錄。想象一下,我們想要在每次調(diào)用特定方法時記錄日志。我們可以通過創(chuàng)建一個修改方法的 ClassVisitor 來做到這一點:

public class LoggingClassVisitor extends ClassVisitor {
    public LoggingClassVisitor(ClassVisitor cv) {
        super(ASM9, cv);
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
        MethodVisitor mv = cv.visitMethod(access, name, descriptor, signature, exceptions);
        if (name.equals("targetMethod")) {
            return new LoggingMethodVisitor(mv);
        }
        return mv;
    }
}

class LoggingMethodVisitor extends MethodVisitor {
    public LoggingMethodVisitor(MethodVisitor mv) {
        super(ASM9, mv);
    }

    @Override
    public void visitCode() {
        mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
        mv.visitLdcInsn("Method called: targetMethod");
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
        super.visitCode();
    }
}

該訪問者在 targetMethod 的開頭添加了一條 println 語句。當我們使用這個訪問者來轉(zhuǎn)換一個類時,每次調(diào)用 targetMethod 時它都會記錄。

字節(jié)碼操作的另一個強大應(yīng)用是性能監(jiān)控。我們可以使用 ASM 在方法周圍添加計時代碼來測量其執(zhí)行時間。以下是我們?nèi)绾螌崿F(xiàn)這一點:

public class TimingClassVisitor extends ClassVisitor {
    public TimingClassVisitor(ClassVisitor cv) {
        super(ASM9, cv);
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
        MethodVisitor mv = cv.visitMethod(access, name, descriptor, signature, exceptions);
        return new TimingMethodVisitor(mv, name);
    }
}

class TimingMethodVisitor extends MethodVisitor {
    private String methodName;

    public TimingMethodVisitor(MethodVisitor mv, String methodName) {
        super(ASM9, mv);
        this.methodName = methodName;
    }

    @Override
    public void visitCode() {
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "nanoTime", "()J", false);
        mv.visitVarInsn(LSTORE, 1);
        super.visitCode();
    }

    @Override
    public void visitInsn(int opcode) {
        if ((opcode >= IRETURN && opcode <= RETURN) || opcode == ATHROW) {
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "nanoTime", "()J", false);
            mv.visitVarInsn(LLOAD, 1);
            mv.visitInsn(LSUB);
            mv.visitVarInsn(LSTORE, 3);
            mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
            mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
            mv.visitInsn(DUP);
            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V", false);
            mv.visitLdcInsn("Method " + methodName + " took ");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
            mv.visitVarInsn(LLOAD, 3);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(J)Ljava/lang/StringBuilder;", false);
            mv.visitLdcInsn(" ns");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
        }
        super.visitInsn(opcode);
    }
}

該訪問者添加了代碼來測量每個方法的執(zhí)行時間,并在方法返回時打印出來。

字節(jié)碼操作也可用于安全目的。例如,我們可以添加檢查以確保僅在經(jīng)過正確身份驗證的情況下調(diào)用某些方法。這是一個簡單的例子:

public class SecurityCheckClassVisitor extends ClassVisitor {
    public SecurityCheckClassVisitor(ClassVisitor cv) {
        super(ASM9, cv);
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
        MethodVisitor mv = cv.visitMethod(access, name, descriptor, signature, exceptions);
        if (name.equals("sensitiveMethod")) {
            return new SecurityCheckMethodVisitor(mv);
        }
        return mv;
    }
}

class SecurityCheckMethodVisitor extends MethodVisitor {
    public SecurityCheckMethodVisitor(MethodVisitor mv) {
        super(ASM9, mv);
    }

    @Override
    public void visitCode() {
        mv.visitMethodInsn(INVOKESTATIC, "com/example/SecurityManager", "isAuthorized", "()Z", false);
        Label authorizedLabel = new Label();
        mv.visitJumpInsn(IFNE, authorizedLabel);
        mv.visitTypeInsn(NEW, "java/lang/SecurityException");
        mv.visitInsn(DUP);
        mv.visitLdcInsn("Unauthorized access");
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/SecurityException", "<init>", "(Ljava/lang/String;)V", false);
        mv.visitInsn(ATHROW);
        mv.visitLabel(authorizedLabel);
        super.visitCode();
    }
}

該訪問者在sensitiveMethod 的開頭添加了安全檢查。如果檢查失敗,則會拋出 SecurityException。

字節(jié)碼操作最強大的應(yīng)用之一是動態(tài)代碼優(yōu)化。我們可以使用 ASM 在加載代碼時對其進行分析和優(yōu)化。例如,我們可以實現(xiàn)一個簡單的常量折疊優(yōu)化:

public class ConstantFoldingClassVisitor extends ClassVisitor {
    public ConstantFoldingClassVisitor(ClassVisitor cv) {
        super(ASM9, cv);
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
        MethodVisitor mv = cv.visitMethod(access, name, descriptor, signature, exceptions);
        return new ConstantFoldingMethodVisitor(mv);
    }
}

class ConstantFoldingMethodVisitor extends MethodVisitor {
    public ConstantFoldingMethodVisitor(MethodVisitor mv) {
        super(ASM9, mv);
    }

    @Override
    public void visitInsn(int opcode) {
        if (opcode == IADD || opcode == ISUB || opcode == IMUL || opcode == IDIV) {
            if (mv instanceof InsnList) {
                InsnList insns = (InsnList) mv;
                AbstractInsnNode prev1 = insns.getLast();
                AbstractInsnNode prev2 = prev1.getPrevious();
                if (prev1 instanceof LdcInsnNode && prev2 instanceof LdcInsnNode) {
                    LdcInsnNode ldc1 = (LdcInsnNode) prev1;
                    LdcInsnNode ldc2 = (LdcInsnNode) prev2;
                    if (ldc1.cst instanceof Integer && ldc2.cst instanceof Integer) {
                        int val1 = (Integer) ldc1.cst;
                        int val2 = (Integer) ldc2.cst;
                        int result;
                        switch (opcode) {
                            case IADD: result = val2 + val1; break;
                            case ISUB: result = val2 - val1; break;
                            case IMUL: result = val2 * val1; break;
                            case IDIV: result = val2 / val1; break;
                            default: return;
                        }
                        insns.remove(prev1);
                        insns.remove(prev2);
                        mv.visitLdcInsn(result);
                        return;
                    }
                }
            }
        }
        super.visitInsn(opcode);
    }
}

該訪問者尋找常量算術(shù)運算并用結(jié)果替換它們。例如,它會在編譯時將 2 3 替換為 5。

字節(jié)碼操作也可用于實現(xiàn)面向方面編程(AOP)功能。我們可以使用 ASM 向現(xiàn)有代碼添加橫切關(guān)注點,例如日志記錄、事務(wù)管理或緩存。這是添加事務(wù)管理的簡單示例:

<dependency>
    <groupId>org.ow2.asm</groupId>
    <artifactId>asm</artifactId>
    <version>9.2</version>
</dependency>

該訪問者將事務(wù)管理代碼添加到以“transaction”開頭的方法中。它在方法開始時開始一個事務(wù)并在結(jié)束時提交它。

字節(jié)碼操作的另一個有趣的應(yīng)用是創(chuàng)建動態(tài)代理。我們可以使用 ASM 在運行時生成代理類,該代理類可用于延遲加載或遠程方法調(diào)用等操作。這是一個簡單的例子:

public class LoggingClassVisitor extends ClassVisitor {
    public LoggingClassVisitor(ClassVisitor cv) {
        super(ASM9, cv);
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
        MethodVisitor mv = cv.visitMethod(access, name, descriptor, signature, exceptions);
        if (name.equals("targetMethod")) {
            return new LoggingMethodVisitor(mv);
        }
        return mv;
    }
}

class LoggingMethodVisitor extends MethodVisitor {
    public LoggingMethodVisitor(MethodVisitor mv) {
        super(ASM9, mv);
    }

    @Override
    public void visitCode() {
        mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
        mv.visitLdcInsn("Method called: targetMethod");
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
        super.visitCode();
    }
}

此生成器創(chuàng)建一個代理類,該代理類實現(xiàn)給定的接口并將所有方法調(diào)用委托給 InvocableHandler。

字節(jié)碼操作也可用于調(diào)試和分析工具。我們可以使用 ASM 添加工具來幫助我們了解程序的行為方式。例如,我們可以添加代碼來跟蹤方法執(zhí)行路徑:

public class TimingClassVisitor extends ClassVisitor {
    public TimingClassVisitor(ClassVisitor cv) {
        super(ASM9, cv);
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
        MethodVisitor mv = cv.visitMethod(access, name, descriptor, signature, exceptions);
        return new TimingMethodVisitor(mv, name);
    }
}

class TimingMethodVisitor extends MethodVisitor {
    private String methodName;

    public TimingMethodVisitor(MethodVisitor mv, String methodName) {
        super(ASM9, mv);
        this.methodName = methodName;
    }

    @Override
    public void visitCode() {
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "nanoTime", "()J", false);
        mv.visitVarInsn(LSTORE, 1);
        super.visitCode();
    }

    @Override
    public void visitInsn(int opcode) {
        if ((opcode >= IRETURN && opcode <= RETURN) || opcode == ATHROW) {
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "nanoTime", "()J", false);
            mv.visitVarInsn(LLOAD, 1);
            mv.visitInsn(LSUB);
            mv.visitVarInsn(LSTORE, 3);
            mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
            mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
            mv.visitInsn(DUP);
            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V", false);
            mv.visitLdcInsn("Method " + methodName + " took ");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
            mv.visitVarInsn(LLOAD, 3);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(J)Ljava/lang/StringBuilder;", false);
            mv.visitLdcInsn(" ns");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
        }
        super.visitInsn(opcode);
    }
}

該訪問者在每個方法的入口和出口點添加日志記錄,使我們能夠跟蹤程序的執(zhí)行路徑。

最后,讓我們看看如何使用 ASM 來實現(xiàn)自定義類加載器。這對于熱交換代碼或?qū)崿F(xiàn)插件系統(tǒng)等事情很有用:

public class SecurityCheckClassVisitor extends ClassVisitor {
    public SecurityCheckClassVisitor(ClassVisitor cv) {
        super(ASM9, cv);
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
        MethodVisitor mv = cv.visitMethod(access, name, descriptor, signature, exceptions);
        if (name.equals("sensitiveMethod")) {
            return new SecurityCheckMethodVisitor(mv);
        }
        return mv;
    }
}

class SecurityCheckMethodVisitor extends MethodVisitor {
    public SecurityCheckMethodVisitor(MethodVisitor mv) {
        super(ASM9, mv);
    }

    @Override
    public void visitCode() {
        mv.visitMethodInsn(INVOKESTATIC, "com/example/SecurityManager", "isAuthorized", "()Z", false);
        Label authorizedLabel = new Label();
        mv.visitJumpInsn(IFNE, authorizedLabel);
        mv.visitTypeInsn(NEW, "java/lang/SecurityException");
        mv.visitInsn(DUP);
        mv.visitLdcInsn("Unauthorized access");
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/SecurityException", "<init>", "(Ljava/lang/String;)V", false);
        mv.visitInsn(ATHROW);
        mv.visitLabel(authorizedLabel);
        super.visitCode();
    }
}

這個類加載器將給定的 ClassVisitor 應(yīng)用于它加載的每個類,允許我們在加載類時對其進行轉(zhuǎn)換。

總之,使用 ASM 進行 Java 字節(jié)碼操作是一項強大的技術(shù),它為增強和優(yōu)化 Java 應(yīng)用程序開辟了一個充滿可能性的世界。從添加日志記錄和性能監(jiān)控到實現(xiàn)面向方面的編程功能和創(chuàng)建動態(tài)代理,應(yīng)用程序種類繁多。雖然需要對 Java 字節(jié)碼和 JVM 有深入的了解,但掌握這些技術(shù)可以極大地增強我們編寫強大且靈活的 Java 應(yīng)用程序的能力。


我們的創(chuàng)作

一定要看看我們的創(chuàng)作:

投資者中心 | 智能生活 | 時代與回響 | 令人費解的謎團 | 印度教 | 精英開發(fā) | JS學校


我們在媒體上

科技考拉洞察 | 時代與回響世界 | 投資者中央媒體 | 令人費解的謎團 | 科學與時代媒介 | 現(xiàn)代印度教

以上是掌握 Java 字節(jié)碼:使用 ASM 庫增強應(yīng)用程序的功能的詳細內(nèi)容。更多信息請關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻,版權(quán)歸原作者所有,本站不承擔相應(yīng)法律責任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機

Video Face Swap

Video Face Swap

使用我們完全免費的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

Java中可呼叫和可運行的差異 Java中可呼叫和可運行的差異 Jul 04, 2025 am 02:50 AM

Callable和Runnable在Java中主要有三點區(qū)別。第一,Callable的call()方法可以返回結(jié)果,適合需要返回值的任務(wù),如Callable;而Runnable的run()方法無返回值,適用于無需返回的任務(wù),如日志記錄。第二,Callable允許拋出checked異常,便于錯誤傳遞;而Runnable必須在內(nèi)部處理異常。第三,Runnable可直接傳給Thread或ExecutorService,而Callable只能提交給ExecutorService,并返回Future對象以

現(xiàn)代爪哇的異步編程技術(shù) 現(xiàn)代爪哇的異步編程技術(shù) Jul 07, 2025 am 02:24 AM

Java支持異步編程的方式包括使用CompletableFuture、響應(yīng)式流(如ProjectReactor)以及Java19 中的虛擬線程。1.CompletableFuture通過鏈式調(diào)用提升代碼可讀性和維護性,支持任務(wù)編排和異常處理;2.ProjectReactor提供Mono和Flux類型實現(xiàn)響應(yīng)式編程,具備背壓機制和豐富的操作符;3.虛擬線程減少并發(fā)成本,適用于I/O密集型任務(wù),與傳統(tǒng)平臺線程相比更輕量且易于擴展。每種方式均有適用場景,應(yīng)根據(jù)需求選擇合適工具并避免混合模型以保持簡潔性

了解Java Nio及其優(yōu)勢 了解Java Nio及其優(yōu)勢 Jul 08, 2025 am 02:55 AM

JavaNIO是Java1.4引入的新型IOAPI,1)面向緩沖區(qū)和通道,2)包含Buffer、Channel和Selector核心組件,3)支持非阻塞模式,4)相比傳統(tǒng)IO更高效處理并發(fā)連接。其優(yōu)勢體現(xiàn)在:1)非阻塞IO減少線程開銷,2)Buffer提升數(shù)據(jù)傳輸效率,3)Selector實現(xiàn)多路復(fù)用,4)內(nèi)存映射加快文件讀寫。使用時需注意:1)Buffer的flip/clear操作易混淆,2)非阻塞下需手動處理不完整數(shù)據(jù),3)Selector注冊需及時取消,4)NIO并非適用于所有場景。

在Java中使用枚舉的最佳實踐 在Java中使用枚舉的最佳實踐 Jul 07, 2025 am 02:35 AM

在Java中,枚舉(enum)適合表示固定常量集合,最佳實踐包括:1.用enum表示固定狀態(tài)或選項,提升類型安全和可讀性;2.為枚舉添加屬性和方法以增強靈活性,如定義字段、構(gòu)造函數(shù)、輔助方法等;3.使用EnumMap和EnumSet提高性能和類型安全性,因其基于數(shù)組實現(xiàn)更高效;4.避免濫用enum,如動態(tài)值、頻繁變更或復(fù)雜邏輯場景應(yīng)使用其他方式替代。正確使用enum能提升代碼質(zhì)量并減少錯誤,但需注意其適用邊界。

Java Classloader在內(nèi)部如何工作 Java Classloader在內(nèi)部如何工作 Jul 06, 2025 am 02:53 AM

Java的類加載機制通過ClassLoader實現(xiàn),其核心工作流程分為加載、鏈接和初始化三個階段。加載階段由ClassLoader動態(tài)讀取類的字節(jié)碼并創(chuàng)建Class對象;鏈接包括驗證類的正確性、為靜態(tài)變量分配內(nèi)存及解析符號引用;初始化則執(zhí)行靜態(tài)代碼塊和靜態(tài)變量賦值。類加載采用雙親委派模型,優(yōu)先委托父類加載器查找類,依次嘗試Bootstrap、Extension和ApplicationClassLoader,確保核心類庫安全且避免重復(fù)加載。開發(fā)者可自定義ClassLoader,如URLClassL

探索Java中不同的同步機制 探索Java中不同的同步機制 Jul 04, 2025 am 02:53 AM

Javaprovidesmultiplesynchronizationtoolsforthreadsafety.1.synchronizedblocksensuremutualexclusionbylockingmethodsorspecificcodesections.2.ReentrantLockoffersadvancedcontrol,includingtryLockandfairnesspolicies.3.Conditionvariablesallowthreadstowaitfor

有效處理常見的Java例外 有效處理常見的Java例外 Jul 05, 2025 am 02:35 AM

Java異常處理的關(guān)鍵在于區(qū)分checked和unchecked異常并合理使用try-catch、finally及日志記錄。1.checked異常如IOException需強制處理,適用于可預(yù)期的外部問題;2.unchecked異常如NullPointerException通常由程序邏輯錯誤引起,屬于運行時錯誤;3.捕獲異常時應(yīng)具體明確,避免籠統(tǒng)捕獲Exception;4.推薦使用try-with-resources自動關(guān)閉資源,減少手動清理代碼;5.異常處理中應(yīng)結(jié)合日志框架記錄詳細信息,便于后

Hashmap在Java內(nèi)部如何工作? Hashmap在Java內(nèi)部如何工作? Jul 15, 2025 am 03:10 AM

HashMap在Java中通過哈希表實現(xiàn)鍵值對存儲,其核心在于快速定位數(shù)據(jù)位置。1.首先使用鍵的hashCode()方法生成哈希值,并通過位運算轉(zhuǎn)換為數(shù)組索引;2.不同對象可能產(chǎn)生相同哈希值,導致沖突,此時以鏈表形式掛載節(jié)點,JDK8后鏈表過長(默認長度8)則轉(zhuǎn)為紅黑樹提升效率;3.使用自定義類作鍵時必須重寫equals()和hashCode()方法;4.HashMap動態(tài)擴容,當元素數(shù)超過容量乘以負載因子(默認0.75)時,擴容并重新哈希;5.HashMap非線程安全,多線程下應(yīng)使用Concu

See all articles