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

Java static 與 final關(guān)鍵字實例詳解

 更新時間:2026年01月26日 09:20:06   作者:J_liaty  
本文詳細介紹了Java中的static和final關(guān)鍵字,包括它們的本質(zhì)、內(nèi)存分配、線程安全問題以及在類加載過程中的內(nèi)存變化,通過舉例和解釋,感興趣的朋友跟隨小編一起看看吧

深入理解 Java 中 static 和 final 關(guān)鍵字的本質(zhì),掌握類加載過程中的內(nèi)存變化,以及在多線程環(huán)境下的線程安全問題。

核心概念速覽

static:屬于類而非實例

本質(zhì):聲明為 static 的成員(變量、方法、代碼塊、內(nèi)部類)屬于類本身,而非任何對象實例。

內(nèi)存分配:在類加載時,static 成員分配在方法區(qū)(JDK 8+ 為元空間+堆的靜態(tài)存儲區(qū)),只有一份副本,所有實例共享。

final:不可變

本質(zhì):聲明為 final 的內(nèi)容一旦初始化就不能改變。

適用范圍

  • :不能被繼承(如 String
  • 方法:不能被子類重寫
  • 變量:引用不可變(基本類型值不變,對象引用地址不變)

static final:全局常量

本質(zhì):既是類級別的,又是不可變的。通常用于定義編譯期常量。

內(nèi)存優(yōu)化:編譯時常量會被編譯器內(nèi)聯(lián)到使用處,不會觸發(fā)類加載。

static 詳解

四種使用形式

1. 靜態(tài)變量(類變量)

public class Counter {
    // 靜態(tài)變量 - 所有實例共享
    private static int count = 0;
    public Counter() {
        count++;  // 每創(chuàng)建一個實例,count 加 1
    }
    public static int getCount() {
        return count;
    }
}

2. 靜態(tài)常量

public class MathConstants {
    // 公開靜態(tài)常量
    public static final double PI = 3.141592653589793;
    public static final double E = 2.718281828459045;
    // 私有靜態(tài)常量
    private static final int MAX_PRECISION = 100;
}

3. 靜態(tài)代碼塊

public class DatabaseConfig {
    private static Properties config;
    // 靜態(tài)代碼塊 - 類加載時執(zhí)行一次
    static {
        config = new Properties();
        try (InputStream input = DatabaseConfig.class.getResourceAsStream("/config.properties")) {
            config.load(input);
        } catch (IOException e) {
            throw new RuntimeException("加載配置文件失敗", e);
        }
    }
    public static String get(String key) {
        return config.getProperty(key);
    }
}

4. 靜態(tài)方法

public class StringUtils {
    // 工具類方法,無需創(chuàng)建對象
    public static boolean isEmpty(String str) {
        return str == null || str.length() == 0;
    }
    public static String capitalize(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }
}

5. 靜態(tài)內(nèi)部類

public class Outer {
    private static int outerStatic = 10;
    private int outerInstance = 20;
    // 靜態(tài)內(nèi)部類
    public static class StaticInner {
        private int innerVar = 30;
        public void show() {
            // 可以訪問外部類的靜態(tài)成員
            System.out.println("outerStatic = " + outerStatic);
            // 不能訪問外部類的實例成員
            // System.out.println(outerInstance); // 編譯錯誤
        }
    }
    public static void main(String[] args) {
        Outer.StaticInner inner = new Outer.StaticInner();
        inner.show();
    }
}

static 的內(nèi)存特點

public class StaticMemoryDemo {
    static int a = 10;      // 存儲在方法區(qū)
    int b = 20;             // 存儲在堆中
    public static void main(String[] args) {
        StaticMemoryDemo obj1 = new StaticMemoryDemo();
        StaticMemoryDemo obj2 = new StaticMemoryDemo();
        // 修改靜態(tài)變量
        StaticMemoryDemo.a = 100;
        obj1.b = 200;
        obj2.b = 300;
        System.out.println(obj1.a + ", " + obj1.b);  // 100, 200
        System.out.println(obj2.a + ", " + obj2.b);  // 100, 300
        // 修改實例變量不影響靜態(tài)變量
        obj1.a = 1000;  // 等價于 StaticMemoryDemo.a = 1000
        System.out.println(StaticMemoryDemo.a);      // 1000
    }
}

final 詳解

三種使用形式

1. final 類

// final 類不能被繼承
public final class String {
    // String 類的實現(xiàn)
}
// 編譯錯誤
// public class MyString extends String {}

2. final 方法

public class Parent {
    // final 方法不能被子類重寫
    public final void essentialMethod() {
        System.out.println("重要方法,不允許修改行為");
    }
    public void normalMethod() {
        System.out.println("普通方法,可以重寫");
    }
}
public class Child extends Parent {
    @Override
    public void normalMethod() {
        System.out.println("重寫普通方法");
    }
    // 編譯錯誤
    // @Override
    // public void essentialMethod() {}
}

3. final 變量

public class FinalVariableDemo {
    // final 實例變量 - 必須初始化
    private final int x;  // 方式1:構(gòu)造器初始化
    private final int y = 20;  // 方式2:聲明時初始化
    // final 靜態(tài)變量
    private static final int STATIC_FINAL = 30;
    // final 實例變量 - 方式3:實例代碼塊初始化
    private final int z;
    {
        z = 40;
    }
    public FinalVariableDemo(int x) {
        this.x = x;
    }
    // final 參數(shù) - 參數(shù)不可修改
    public void process(final int data, final String str) {
        // data = 10;  // 編譯錯誤
        // str = "new";  // 編譯錯誤
        System.out.println(data + ", " + str);
    }
    // final 局部變量
    public void localFinal() {
        final int local = 100;
        // local = 200;  // 編譯錯誤
    }
}

final 的內(nèi)存安全特性

public class FinalObjectDemo {
    public static void main(String[] args) {
        // final 對象 - 引用不可變,但內(nèi)容可變
        final List<String> list = new ArrayList<>();
        list.add("A");        // ? 合法:對象內(nèi)容可變
        list.add("B");
        list.remove(0);
        // list = new ArrayList<>();  // ? 非法:引用不可重新賦值
        // final 數(shù)組同理
        final int[] arr = {1, 2, 3};
        arr[0] = 100;         // ? 合法:數(shù)組元素可變
        // arr = new int[5];    // ? 非法:引用不可變
    }
}

static final 組合使用

常量定義的最佳實踐

/**
 * 全局常量定義
 */
public final class GlobalConstants {
    // 私有構(gòu)造器,防止實例化
    private GlobalConstants() {}
    // 編譯期常量 - 編譯器會內(nèi)聯(lián)
    public static final int MAX_CONNECTIONS = 100;
    public static final long TIMEOUT_MS = 5000L;
    // 運行時常量 - 需要類加載
    public static final String APP_VERSION = "1.0.0";
    public static final String JAVA_VERSION = System.getProperty("java.version");
    // 不可變集合
    public static final List<String> SUPPORTED_FORMATS = 
        Collections.unmodifiableList(Arrays.asList("JSON", "XML", "YAML"));
    // 不可變 Map
    public static final Map<String, Integer> ERROR_CODES;
    static {
        Map<String, Integer> codes = new HashMap<>();
        codes.put("NOT_FOUND", 404);
        codes.put("SERVER_ERROR", 500);
        ERROR_CODES = Collections.unmodifiableMap(codes);
    }
}

常量在內(nèi)存中的優(yōu)化

public class ConstantOptimization {
    // 編譯期常量 - 會被內(nèi)聯(lián)
    public static final int MAX_SIZE = 100;
    // 運行時常量 - 不會內(nèi)聯(lián)
    public static final String CONFIG_PATH = System.getProperty("config.path");
    public static void main(String[] args) {
        // 使用編譯期常量時,編譯器會直接替換為 100
        // 不會觸發(fā) ConstantOptimization 類的加載
        int size = ConstantOptimization.MAX_SIZE;
        // 使用運行時常量時,會觸發(fā)類加載
        String path = ConstantOptimization.CONFIG_PATH;
    }
}

類加載過程中的內(nèi)存變化

類加載的生命周期

加載 → 鏈接(驗證→準備→解析) → 初始化 → 使用 → 卸載

詳細過程解析

階段 1:加載(Loading)

JVM 讀取類的字節(jié)碼文件(.class),在內(nèi)存中生成一個代表這個類的 java.lang.Class 對象。

此時內(nèi)存中

  • 方法區(qū)開始準備存儲類的運行時數(shù)據(jù)結(jié)構(gòu)
  • static final編譯期常量(如 MAX_SIZE = 100不會觸發(fā)類加載,因為已被編譯器內(nèi)聯(lián)

階段 2:鏈接(Linking)

2.1 驗證(Verification)

確保加載的類信息符合 JVM 規(guī)范,沒有安全風(fēng)險。

2.2 準備(Preparation)- 關(guān)鍵階段

為類的靜態(tài)變量分配內(nèi)存,并設(shè)置默認初始值。

public class PreparationDemo {
    // 準備階段后的狀態(tài):
    static int a = 10;           // a = 0(零值)
    static boolean b = true;     // b = false(零值)
    static char c = 'A';         // c = '\u0000'(零值)
    static long d = 100L;        // d = 0L(零值)
    // 引用類型:null
    static String e = "hello";   // e = null(零值)
    // static final 編譯期常量:直接設(shè)置為最終值
    static final int f = 20;     // f = 20(最終值)
    // static final 運行時常量:先設(shè)為零值
    static final Random rand = new Random();
    static final int g = rand.nextInt(100);  // g = 0(零值)
}

內(nèi)存分配

  • static 變量在方法區(qū)分配內(nèi)存,設(shè)置零值(0, null, false)
  • static final 的編譯期常量(如 f = 20)直接設(shè)置為最終值
  • static final 的運行時常量(如 g)先設(shè)為零值,初始化階段才賦真值
2.3 解析(Resolution)

將常量池中的符號引用替換為直接引用。

階段 3:初始化(Initialization)- 真正賦值

執(zhí)行 <clinit> 方法(類構(gòu)造器),按代碼順序初始化靜態(tài)變量和執(zhí)行靜態(tài)代碼塊。

public class InitializationDemo {
    static int a = 10;           // 第1步:a = 10
    static {
        System.out.println("靜態(tài)代碼塊1: a = " + a);  // 第2步:輸出 a = 10
        a = 20;                   // 第3步:a = 20
    }
    static int b = 30;            // 第4步:b = 30
    static {
        System.out.println("靜態(tài)代碼塊2: a = " + a + ", b = " + b);
        // 第5步:輸出 a = 20, b = 30
    }
    public static void main(String[] args) {
        System.out.println("最終值: a = " + a + ", b = " + b);
        // 第6步:輸出 最終值: a = 20, b = 30
    }
}

輸出結(jié)果

靜態(tài)代碼塊1: a = 10
靜態(tài)代碼塊2: a = 20, b = 30
最終值: a = 20, b = 30

階段 4:使用(Using)

public class UsingDemo {
    public static void main(String[] args) {
        // 主動引用 - 會觸發(fā)類初始化
        int count = Counter.getCount();  // 觸發(fā) Counter 類加載
        // 被動引用 - 不會觸發(fā)類初始化
        int[] arr = new int[10];  // 不會觸發(fā)數(shù)組類型的父類初始化
        // 訪問編譯期常量 - 不觸發(fā)類初始化
        int max = Constants.MAX_SIZE;  // 不觸發(fā) Constants 類加載
        // 訪問運行時常量 - 觸發(fā)類初始化
        String ver = Constants.VERSION;  // 觸發(fā) Constants 類加載
    }
}

線程安全問題

static 變量的線程安全問題

問題示例

public class UnsafeCounter {
    // 非線程安全的計數(shù)器
    private static int count = 0;
    public static void increment() {
        count++;  // 非原子操作,存在競態(tài)條件
    }
    public static int getCount() {
        return count;
    }
}

count++ 的實際操作:

  1. 讀取 count 的值
  2. 將 count 加 1
  3. 將新值寫回 count

在多線程環(huán)境下,這三個步驟可能被交叉執(zhí)行,導(dǎo)致數(shù)據(jù)不一致。

解決方案 1:使用 synchronized

public class SafeCounterWithSync {
    private static int count = 0;
    // 使用類鎖保護靜態(tài)變量
    public synchronized static void increment() {
        count++;
    }
    public synchronized static int getCount() {
        return count;
    }
}

解決方案 2:使用 AtomicInteger

import java.util.concurrent.atomic.AtomicInteger;
public class SafeCounterWithAtomic {
    private static final AtomicInteger count = new AtomicInteger(0);
    public static void increment() {
        count.incrementAndGet();  // 原子操作
    }
    public static int getCount() {
        return count.get();
    }
}

解決方案 3:使用 LongAdder(高并發(fā)場景)

import java.util.concurrent.atomic.LongAdder;
public class HighPerformanceCounter {
    private static final LongAdder count = new LongAdder();
    public static void increment() {
        count.increment();
    }
    public static long getCount() {
        return count.sum();
    }
}

static 代碼塊的線程安全

問題:靜態(tài)代碼塊只執(zhí)行一次,但初始化可能涉及復(fù)雜操作

public class UnsafeSingleton {
    private static UnsafeSingleton instance;
    static {
        // 復(fù)雜的初始化邏輯
        try {
            Thread.sleep(100);  // 模擬耗時操作
            instance = new UnsafeSingleton();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    private UnsafeSingleton() {}
    public static UnsafeSingleton getInstance() {
        return instance;
    }
}

解決方案:使用靜態(tài)內(nèi)部類(延遲加載 + 線程安全)

public class ThreadSafeSingleton {
    private ThreadSafeSingleton() {}
    // 靜態(tài)內(nèi)部類 - 延遲加載
    private static class Holder {
        private static final ThreadSafeSingleton INSTANCE = new ThreadSafeSingleton();
    }
    public static ThreadSafeSingleton getInstance() {
        return Holder.INSTANCE;
    }
}

final 的線程安全特性

final 字段的初始化安全性

public class FinalExample {
    private final int x;
    private int y;
    public FinalExample() {
        x = 1;  // final 字段在構(gòu)造器完成前對其他線程可見
        y = 2;  // 普通字段可能在對象引用逸出后仍未完成初始化
    }
    public static void main(String[] args) {
        // 線程 A 創(chuàng)建對象
        FinalExample obj = new FinalExample();
        // 線程 B 直接讀取對象
        // obj.x 保證可見(1),obj.y 可能是 0
    }
}

JMM 保證:只要對象引用對其他線程可見,那么 final 字段也一定初始化完成。

final 不可變對象的線程安全

public final class ImmutablePerson {
    private final String name;
    private final int age;
    private final List<String> hobbies;
    public ImmutablePerson(String name, int age, List<String> hobbies) {
        this.name = name;
        this.age = age;
        // 防御性拷貝
        this.hobbies = Collections.unmodifiableList(new ArrayList<>(hobbies));
    }
    // 只提供 getter,不提供 setter
    public String getName() {
        return name;
    }
    public int getAge() {
        return age;
    }
    public List<String> getHobbies() {
        return hobbies;
    }
}

static final 常量的線程安全

public class ThreadSafeConstants {
    // 編譯期常量 - 線程安全(只讀)
    public static final int MAX_SIZE = 100;
    // 運行時常量 - 線程安全(final 保證不可變)
    public static final String APP_NAME = "MyApp";
    // 不可變集合 - 線程安全
    public static final List<String> SAFE_LIST = 
        Collections.unmodifiableList(Arrays.asList("A", "B", "C"));
    // 即使在多線程環(huán)境下訪問,也不需要同步
    public static void main(String[] args) {
        new Thread(() -> {
            System.out.println(MAX_SIZE);  // 安全
        }).start();
        new Thread(() -> {
            System.out.println(APP_NAME);  // 安全
        }).start();
    }
}

常見并發(fā)陷阱

陷阱 1:誤以為 final 保證對象內(nèi)容不可變

public class FinalNotImmutable {
    public static void main(String[] args) {
        final Map<String, Integer> map = new HashMap<>();
        map.put("A", 1);  // ? 合法
        // 多線程環(huán)境下修改 final 對象的內(nèi)容 - 不安全!
        new Thread(() -> map.put("B", 2)).start();
        new Thread(() -> map.put("C", 3)).start();
    }
}

解決方案:使用不可變集合

public class ImmutableMapExample {
    private static final Map<String, Integer> SAFE_MAP;
    static {
        Map<String, Integer> temp = new HashMap<>();
        temp.put("A", 1);
        temp.put("B", 2);
        SAFE_MAP = Collections.unmodifiableMap(temp);  // 不可變
    }
    public static int getValue(String key) {
        return SAFE_MAP.get(key);  // 線程安全
    }
}

陷阱 2:static 初始化的可見性問題

public class StaticVisibility {
    private static boolean initialized = false;
    private static Data data;
    static {
        data = new Data();  // 初始化數(shù)據(jù)
        initialized = true; // 標記已初始化
    }
    public static Data getData() {
        if (!initialized) {  // 可能讀到舊的 initialized 值
            throw new IllegalStateException("Not initialized");
        }
        return data;  // 可能 data 未完成初始化
    }
}

解決方案:使用 volatile 或確保類初始化的原子性

public class StaticVisibilityFixed {
    // volatile 保證 happens-before 關(guān)系
    private static volatile boolean initialized = false;
    private static Data data;
    static {
        data = new Data();
        initialized = true;  // volatile 寫保證之前的操作對其他線程可見
    }
    public static Data getData() {
        if (!initialized) {
            throw new IllegalStateException("Not initialized");
        }
        return data;
    }
}

最佳實踐

static 使用最佳實踐

/**
 * 工具類最佳實踐
 */
public final class CollectionUtils {
    // 私有構(gòu)造器,防止實例化
    private CollectionUtils() {
        throw new AssertionError("工具類不允許實例化");
    }
    // 靜態(tài)工具方法
    public static <T> boolean isEmpty(Collection<T> collection) {
        return collection == null || collection.isEmpty();
    }
    public static <T> boolean isNotEmpty(Collection<T> collection) {
        return !isEmpty(collection);
    }
    public static <T> List<T> emptyIfNull(List<T> list) {
        return list == null ? Collections.emptyList() : list;
    }
}

final 使用最佳實踐

/**
 * 不可變對象最佳實踐
 */
public final class Money {
    private final long amount;
    private final String currency;
    public Money(long amount, String currency) {
        this.amount = amount;
        this.currency = Objects.requireNonNull(currency, "currency cannot be null");
    }
    // 返回新對象,而不是修改原對象
    public Money add(Money other) {
        if (!this.currency.equals(other.currency)) {
            throw new IllegalArgumentException("Currency mismatch");
        }
        return new Money(this.amount + other.amount, this.currency);
    }
    public long getAmount() {
        return amount;
    }
    public String getCurrency() {
        return currency;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Money)) return false;
        Money money = (Money) o;
        return amount == money.amount && currency.equals(money.currency);
    }
    @Override
    public int hashCode() {
        return Objects.hash(amount, currency);
    }
}

單例模式最佳實踐

/**
 * 枚舉單例 - 最佳實踐
 */
public enum EnumSingleton {
    INSTANCE;
    private final DataService dataService;
    EnumSingleton() {
        this.dataService = new DataService();
    }
    public DataService getDataService() {
        return dataService;
    }
}

性能對比

關(guān)鍵字組合對比

關(guān)鍵字組合內(nèi)存分配訪問速度線程安全適用場景
static方法區(qū),全局唯一快(直接訪問)需額外同步工具方法、共享數(shù)據(jù)
final視上下文而定快(編譯器優(yōu)化)不可變保證安全不可變數(shù)據(jù)、方法鎖定
static final方法區(qū),編譯期常量可能內(nèi)聯(lián)最快天然安全(只讀)全局常量、配置項

性能測試示例

public class PerformanceTest {
    private static int staticCount = 0;
    private int instanceCount = 0;
    private static final int STATIC_FINAL_CONSTANT = 100;
    public static void testStatic() {
        staticCount++;  // 直接訪問方法區(qū)
    }
    public void testInstance() {
        instanceCount++;  // 需要通過對象引用
    }
    public void testConstant() {
        int value = STATIC_FINAL_CONSTANT;  // 可能被內(nèi)聯(lián)為 int value = 100
    }
}

總結(jié)

核心要點

  • static 決定歸屬:
    • 屬于類,所有實例共享
    • 在類加載時初始化,存儲在方法區(qū)
    • 訪問速度快,但多線程下需注意線程安全
  • final 決定可變性:
    • 一旦初始化不可改變
    • 提供初始化安全保證
    • 適用于不可變對象設(shè)計
  • static final 決定本質(zhì):
    • 全局常量,編譯期可能內(nèi)聯(lián)
    • 天然線程安全(只讀)
    • 性能最優(yōu)
  • 類加載時序:
    • 準備階段:靜態(tài)變量設(shè)為零值,常量設(shè)為最終值
    • 初始化階段:按代碼順序執(zhí)行靜態(tài)變量賦值和靜態(tài)代碼塊
  • 線程安全:
    • static 變量:需使用 synchronized、AtomicLongAdder
    • static final 常量:天然線程安全
    • final 對象:引用不可變,但內(nèi)容可能需額外保護
    • 靜態(tài)內(nèi)部類單例:延遲加載 + 線程安全

記憶口訣

static 歸類不歸你,final 不變永相依
static final 全局常,編譯內(nèi)聯(lián)性能強
類加載時分兩步,準備初始化要清楚
線程安全需注意,原子操作不可欺

參考資料

到此這篇關(guān)于Java static 與 final關(guān)鍵字詳解的文章就介紹到這了,更多相關(guān)Java static 與 final內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • FeignClientFactoryBean創(chuàng)建動態(tài)代理詳細解讀

    FeignClientFactoryBean創(chuàng)建動態(tài)代理詳細解讀

    這篇文章主要介紹了FeignClientFactoryBean創(chuàng)建動態(tài)代理詳細解讀,當(dāng)直接進去注冊的方法中,一步步放下走,都是直接放bean的定義信息中放入值,然后轉(zhuǎn)成BeanDefinitionHolder,最后在注冊到IOC容器中,需要的朋友可以參考下
    2023-11-11
  • 圖解Java經(jīng)典算法希爾排序的原理與實現(xiàn)

    圖解Java經(jīng)典算法希爾排序的原理與實現(xiàn)

    希爾排序是希爾(Donald Shell)于1959年提出的一種排序算法。希爾排序也是一種插入排序,它是簡單插入排序經(jīng)過改進之后的一個更高效的版本,也稱為縮小增量排序,同時該算法是沖破O(n2)的第一批算法之一。本文會以圖解的方式詳細介紹希爾排序的基本思想及其代碼實現(xiàn)
    2022-09-09
  • Eclipse下使用ANT編譯提示OutOfMemory的解決方法

    Eclipse下使用ANT編譯提示OutOfMemory的解決方法

    由于需要使用ANT編譯的代碼比較多,特別是在第一次變異的時候,會出現(xiàn)OutOfMemory錯誤。并提示更改ANT_OPTS設(shè)定。
    2009-04-04
  • java如何使用jdbc連接TDSQL數(shù)據(jù)庫

    java如何使用jdbc連接TDSQL數(shù)據(jù)庫

    TDSQL是騰訊打造的一款分布式數(shù)據(jù)庫產(chǎn)品,具備強一致高可用、全球部署架構(gòu)、分布式水平擴展、高性能、企業(yè)級安全等特性,本文我們就來看看Java如何使用jdbc連接TDSQL數(shù)據(jù)庫吧
    2025-06-06
  • java之swing單選框用法實例分析

    java之swing單選框用法實例分析

    這篇文章主要介紹了java之swing單選框用法,以實例形式分析了swing圖形界面單選框的實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-09-09
  • 使用Feign配置請求頭以及支持Https協(xié)議

    使用Feign配置請求頭以及支持Https協(xié)議

    這篇文章主要介紹了使用Feign配置請求頭以及支持Https協(xié)議,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • java虛擬機JVM類加載機制原理(面試必問)

    java虛擬機JVM類加載機制原理(面試必問)

    這篇文章主要介紹了面試當(dāng)中必會問到的java虛擬機JVM類加載機制,非常的詳細,有需要的朋友可以借鑒參考下,歡迎多多交流討論
    2021-08-08
  • 淺談序列化之protobuf與avro對比(Java)

    淺談序列化之protobuf與avro對比(Java)

    下面小編就為大家?guī)硪黄獪\談序列化之protobuf與avro對比(Java)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • Spring @Configuration注解及配置方法

    Spring @Configuration注解及配置方法

    這篇文章主要介紹了Spring @Configuration注解及配置方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-04-04
  • SpringSecurity構(gòu)建基于JWT的登錄認證實現(xiàn)

    SpringSecurity構(gòu)建基于JWT的登錄認證實現(xiàn)

    這篇文章主要介紹了SpringSecurity構(gòu)建基于JWT的登錄認證實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02

最新評論

潼南县| 高台县| 郑州市| 抚顺市| 乌拉特中旗| 鲁山县| 大方县| 新源县| 甘德县| 赣榆县| 桐乡市| 台中县| 乌鲁木齐县| 临潭县| 岫岩| 乌兰察布市| 板桥市| 梁河县| 塔河县| 南靖县| 乳源| 定兴县| 鄄城县| 康乐县| 甘洛县| 聂拉木县| 右玉县| 丹阳市| 沭阳县| 永宁县| 综艺| 介休市| 沧州市| 石家庄市| 塘沽区| 乐清市| 卢龙县| 丹寨县| 顺义区| 循化| 阿城市|