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

Java中的char、String、StringBuilder與StringBuffer全方面解析

 更新時(shí)間:2026年02月24日 14:42:40   作者:百錦再@新空間創(chuàng)想科技  
在Java編程中,char、String、StringBuilder和StringBuffer是處理字符和字符串的四個(gè)基石,本文將深入淺出地為你剖析這四大金剛的方方面面,感興趣的朋友跟隨小編一起看看吧

在Java編程中,char、String、StringBuilder和StringBuffer是處理字符和字符串的四個(gè)基石。理解它們的設(shè)計(jì)哲學(xué)、底層實(shí)現(xiàn)和性能差異,對(duì)于編寫高效、健壯的代碼至關(guān)重要。本文將深入淺出地為你剖析這四大金剛的方方面面。

第一章:一切的基礎(chǔ)——char原始類型

在探討復(fù)雜的字符串類之前,我們首先需要了解構(gòu)成字符串的最基本單元:char。

1.1 定義與本質(zhì)

char是Java中的一種原始數(shù)據(jù)類型(Primitive Type),用于表示一個(gè)單一的16位Unicode字符。在Java誕生之初,設(shè)計(jì)者就采用了Unicode字符集,這使得Java天生具有良好的國(guó)際化支持。

  • 大小:16位(2個(gè)字節(jié)),范圍從 065,535\u0000\uffff)。
  • 無(wú)符號(hào)性char是一個(gè)無(wú)符號(hào)類型,這意味著它不能表示負(fù)數(shù)。

1.2 字符編碼的演變:從char到byte

在JDK 9之前,String類的內(nèi)部實(shí)現(xiàn)也是采用 char[] 數(shù)組來(lái)存儲(chǔ)字符。然而,一個(gè)深刻的洞察是,大多數(shù)應(yīng)用程序使用的字符串主要由Latin-1字符集(如英文、數(shù)字)構(gòu)成,這些字符僅需一個(gè)字節(jié)(8位)即可表示,用兩個(gè)字節(jié)的char來(lái)存儲(chǔ)會(huì)造成一半的內(nèi)存浪費(fèi)。

因此,從JDK 9開(kāi)始,為了優(yōu)化內(nèi)存占用,String(以及StringBuilderStringBuffer的底層)不再使用 char[],而是改用了 byte[] 數(shù)組,并引入一個(gè) coder(編碼器)字段來(lái)標(biāo)識(shí)使用的是LATIN1(每個(gè)字符1字節(jié))還是UTF16(每個(gè)字符2字節(jié))編碼。這是一個(gè)非常重要的底層變化,但對(duì)開(kāi)發(fā)者來(lái)說(shuō)是透明的,我們?cè)谶壿嬌弦廊豢梢詫⑺鼈円暈樽址蛄小?/p>

1.3 char的初始化與賦值

char的賦值方式非常靈活,可以通過(guò)以下幾種方式:

  1. 字符字面量:用單引號(hào)括起來(lái)的單個(gè)字符??梢允怯⑽淖帜福部梢允侵形淖址?。
    char c1 = 'A';
    char c2 = '中';
    
  2. 整數(shù)編碼值:直接賦值為字符在Unicode表中的碼點(diǎn)(整數(shù))。
    char c3 = 65;      // 十進(jìn)制,對(duì)應(yīng) 'A'
    char c4 = 0101;    // 八進(jìn)制,對(duì)應(yīng) 'A'
    char c5 = 0x41;    // 十六進(jìn)制,對(duì)應(yīng) 'A'
    
  3. Unicode轉(zhuǎn)義序列:使用 \u 前綴加上4位十六進(jìn)制數(shù)。
    char c6 = '\u0041'; // 對(duì)應(yīng) 'A'
    
  4. 轉(zhuǎn)義字符:表示一些特殊功能字符。
    char c7 = '\n';     // 換行符
    char c8 = '\'';     // 單引號(hào)字符本身
    char c9 = '\\';     // 反斜杠字符本身
    

1.4 char的運(yùn)算

由于char底層存儲(chǔ)的是整數(shù)值,因此它可以進(jìn)行算術(shù)運(yùn)算和比較。

char ch = 'A';
System.out.println("ch is " + ch); // 輸出: ch is A
ch = (char)(ch + 1); // 將 'A' 的碼點(diǎn) (65) 加 1,得到 66,再?gòu)?qiáng)轉(zhuǎn)為 char
System.out.println("ch is now " + ch); // 輸出: ch is now Y
char ch2 = 'a' + 'b'; // 'a'(97) + 'b'(98) = 195,結(jié)果在int范圍內(nèi)
System.out.println(ch2); // 輸出:195對(duì)應(yīng)的字符?這里實(shí)際上輸出的是195作為char類型的字符,需要查碼表。
int sum = 'a' + 'b';
System.out.println(sum); // 輸出: 195

關(guān)鍵點(diǎn):當(dāng) charcharcharint 進(jìn)行運(yùn)算時(shí),結(jié)果會(huì)被提升為 int 類型。如果需要重新賦給 char 變量,必須進(jìn)行顯式的強(qiáng)制類型轉(zhuǎn)換 (char)

第二章:不可變的字符串——String類

String 類是Java中使用頻率最高的類之一,其“不可變性”是其最核心的特征。

2.1 類的定義與不可變性

查看 String 類的源碼(以JDK 8為例,后續(xù)版本底層數(shù)組變?yōu)閎yte[],但邏輯一致),我們可以清晰地看到其不可變性的實(shí)現(xiàn):

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[]; // JDK 9 之后變?yōu)?private final byte[] value
    /** Cache the hash code for the string */
    private int hash; // Default to 0
    // ... 其他代碼
}
  • 類被 final 修飾:這意味著 String 類不能被繼承,防止子類破壞其不可變行為。
  • 存儲(chǔ)數(shù)組被 private final 修飾:value 數(shù)組的引用不可變,且無(wú)法從外部訪問(wèn)。final 保證了數(shù)組的引用一旦指向某個(gè)地址后就不能再改變。雖然沒(méi)有直接的語(yǔ)法阻止數(shù)組內(nèi)部元素的變化,但 String 類沒(méi)有提供任何可以修改數(shù)組元素的方法,從而確保了內(nèi)部的字符數(shù)組也“不可變”。

2.2 不可變性的優(yōu)勢(shì)

這種精心的設(shè)計(jì)帶來(lái)了許多好處:

  • 線程安全:由于對(duì)象內(nèi)容不可變,它可以在多個(gè)線程之間自由共享,無(wú)需任何同步措施。
  • 字符串常量池(String Pool):這是不可變性帶來(lái)的最大性能優(yōu)化之一。當(dāng)創(chuàng)建一個(gè)字符串字面量(如 String s = "hello";)時(shí),JVM會(huì)檢查常量池中是否已存在相同內(nèi)容的字符串。如果存在,則直接返回其引用;如果不存在,則在池中創(chuàng)建新字符串并返回引用。這種機(jī)制極大地節(jié)省了內(nèi)存。
    String s1 = "hello";
    String s2 = "hello";
    System.out.println(s1 == s2); // 輸出 true,因?yàn)橹赶虺A砍刂械耐粋€(gè)對(duì)象
    
  • 哈希值緩存:如上源碼所示,String 類中有一個(gè) hash 字段。因?yàn)樽址豢勺?,其哈希值在第一次?jì)算后就可以被緩存起來(lái),之后直接返回。這使得 String 非常適合作為 HashMapHashTable 的鍵,提高了查找效率。

2.3 創(chuàng)建String對(duì)象的兩種方式

  • 方式一:字面量賦值
    String str1 = "abc";
    這種方式可能會(huì)從字符串常量池中獲取對(duì)象。

  • 方式二:new關(guān)鍵字
    String str2 = new String("abc");
    這種方式一定會(huì)在堆(Heap)中創(chuàng)建一個(gè)新的 String 對(duì)象。如果常量池中還沒(méi)有 "abc" 這個(gè)字符串,JVM會(huì)先在常量池中創(chuàng)建,然后再在堆中創(chuàng)建對(duì)象。因此,這種方式通常會(huì)創(chuàng)建1個(gè)或2個(gè)對(duì)象。

    String s3 = new String("hello");
    String s4 = new String("hello");
    System.out.println(s1 == s3); // 輸出 false,s1指向常量池,s3指向堆
    System.out.println(s3 == s4); // 輸出 false,s3和s4指向堆中不同的對(duì)象
    

2.4 操作的真相:總是生成新對(duì)象

理解了不可變性,就不難明白,對(duì) String 對(duì)象的任何修改操作(如拼接、替換、截?。疾皇窃谠瓕?duì)象上進(jìn)行的,而是返回一個(gè)新的 String 對(duì)象。

String original = "Hello";
String modified = original.concat(" World");
System.out.println(original); // 輸出: Hello (原對(duì)象未變)
System.out.println(modified); // 輸出: Hello World (新對(duì)象)
String upper = original.toUpperCase();
System.out.println(original); // 輸出: Hello
System.out.println(upper);    // 輸出: HELLO

2.5 字符串拼接的陷阱與優(yōu)化

正是由于上述特性,在循環(huán)中使用 + 進(jìn)行字符串拼接會(huì)帶來(lái)嚴(yán)重的性能問(wèn)題。

// 低效的寫法
String result = "";
for (int i = 0; i < 1000; i++) {
    result = result + i; // 每次循環(huán)都會(huì)創(chuàng)建新的String對(duì)象
}

在JDK 5之后,Java編譯器會(huì)對(duì) + 運(yùn)算符進(jìn)行優(yōu)化,自動(dòng)將其轉(zhuǎn)換為 StringBuilderappend 操作。例如 String c = a + b; 會(huì)被編譯為 (new StringBuilder()).append(a).append(b).toString();。但是,在循環(huán)體內(nèi),這種優(yōu)化依然會(huì)導(dǎo)致每次循環(huán)都新建一個(gè) StringBuilder 對(duì)象,反編譯后的字節(jié)碼可以清晰地證明這一點(diǎn)。因此,在循環(huán)或頻繁修改字符串的場(chǎng)景下,我們必須手動(dòng)使用 StringBuilderStringBuffer。

第三章:可變的字符序列——StringBuilder與StringBuffer

為了解決 String 不可變帶來(lái)的性能問(wèn)題,Java提供了兩個(gè)可變的字符序列類:StringBuilderStringBuffer。它們都繼承自 AbstractStringBuilder 類,底層使用可變的字符數(shù)組(JDK 9后為byte[])來(lái)存儲(chǔ)數(shù)據(jù)。

3.1 AbstractStringBuilder:共同的祖先

雖然我們不能直接使用 AbstractStringBuilder,但它是理解這兩個(gè)類的關(guān)鍵。

// 以JDK 8為例
abstract class AbstractStringBuilder implements Appendable, CharSequence {
    char[] value; // 非final,存儲(chǔ)字符序列,JDK 9后變?yōu)?byte[]
    int count;    // 已使用的字符個(gè)數(shù)
    // 擴(kuò)容機(jī)制
    public void ensureCapacity(int minimumCapacity) {
        if (minimumCapacity > value.length) {
            expandCapacity(minimumCapacity);
        }
    }
    void expandCapacity(int minimumCapacity) {
        int newCapacity = value.length * 2 + 2; // 新容量通常是舊容量的2倍+2
        if (newCapacity < minimumCapacity) {
            newCapacity = minimumCapacity;
        }
        // 創(chuàng)建新數(shù)組并復(fù)制原數(shù)據(jù)
        value = Arrays.copyOf(value, newCapacity);
    }
    // ...
}
  • 可變性value 數(shù)組沒(méi)有被 final 修飾,可以被重新賦值指向一個(gè)新的數(shù)組地址,也可以修改數(shù)組內(nèi)部元素。
  • 自動(dòng)擴(kuò)容:當(dāng)調(diào)用 appendinsert 方法時(shí),如果當(dāng)前字符序列的長(zhǎng)度超過(guò)了底層數(shù)組的容量,它會(huì)自動(dòng)觸發(fā) expandCapacity 方法,創(chuàng)建一個(gè)更大的新數(shù)組(通常是原容量的2倍+2),并將原內(nèi)容復(fù)制過(guò)去。

3.2 StringBuilder:非線程安全的“快槍手”

  • 誕生時(shí)間:JDK 1.5引入。
  • 核心特點(diǎn)非線程安全。它的所有方法(如 append, insert, delete 等)都沒(méi)有使用 synchronized 關(guān)鍵字進(jìn)行同步。
  • 適用場(chǎng)景單線程環(huán)境下操作字符串緩沖區(qū)。因?yàn)楸苊饬随i的競(jìng)爭(zhēng)和獲取開(kāi)銷,它通常擁有最好的性能,是單線程字符串操作的默認(rèn)選擇。

3.3 StringBuffer:線程安全的“老大哥”

  • 誕生時(shí)間:JDK 1.0就已存在。
  • 核心特點(diǎn)線程安全。它的絕大多數(shù)方法都使用了 synchronized 關(guān)鍵字修飾,確保在多線程并發(fā)訪問(wèn)時(shí),不會(huì)出現(xiàn)數(shù)據(jù)錯(cuò)亂的問(wèn)題。
    // StringBuffer 的 append 方法
    @Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }
    
  • 適用場(chǎng)景多線程環(huán)境下,多個(gè)線程可能同時(shí)操作同一個(gè) StringBuffer 對(duì)象時(shí)。在這種場(chǎng)景下,為了保證數(shù)據(jù)的正確性,必須使用 StringBuffer。

3.4 核心API對(duì)比

三個(gè)類都實(shí)現(xiàn)了 CharSequence 接口,因此它們的方法非常相似。StringBuilderStringBuffer 的API是兼容的,可以無(wú)縫替換。

方法分類常用方法描述
構(gòu)造器StringBuilder() / StringBuffer()創(chuàng)建一個(gè)初始容量為16字符的空對(duì)象。
StringBuilder(int capacity)指定初始容量。
StringBuilder(String str)根據(jù)字符串創(chuàng)建,初始容量為 16 + str.length()
追加append(任意類型 x)將參數(shù)的字符串表示形式追加到序列末尾。這是最常用的方法,支持重載。
插入insert(int offset, 任意類型 x)在指定位置插入?yún)?shù)的字符串表示形式。
刪除delete(int start, int end)刪除從 startend-1 的子序列。
deleteCharAt(int index)刪除指定位置的字符。
替換與反轉(zhuǎn)replace(int start, int end, String str)str 替換指定范圍的字符。
reverse()將序列反轉(zhuǎn)。
修改setCharAt(int index, char ch)修改指定位置的字符。
查詢charAt(int index) / length()獲取指定字符/長(zhǎng)度。
indexOf(String str) / lastIndexOf(String str)查找子串位置。
轉(zhuǎn)StringtoString()返回此序列中數(shù)據(jù)的字符串表示形式。

3.5 性能對(duì)比

下面通過(guò)一個(gè)簡(jiǎn)單的性能測(cè)試來(lái)直觀感受三者的差異:

public class PerformanceTest {
    private static final int TIMES = 20000;
    public static void main(String[] args) {
        testString();
        testStringBuffer();
        testStringBuilder();
    }
    public static void testString() {
        long start = System.currentTimeMillis();
        String str = "";
        for (int i = 0; i < TIMES; i++) {
            str += "java";
        }
        long end = System.currentTimeMillis();
        System.out.println("String 拼接耗時(shí): " + (end - start) + "ms");
    }
    public static void testStringBuffer() {
        long start = System.currentTimeMillis();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < TIMES; i++) {
            sb.append("java");
        }
        String str = sb.toString();
        long end = System.currentTimeMillis();
        System.out.println("StringBuffer 拼接耗時(shí): " + (end - start) + "ms");
    }
    public static void testStringBuilder() {
        long start = System.currentTimeMillis();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < TIMES; i++) {
            sb.append("java");
        }
        String str = sb.toString();
        long end = System.currentTimeMillis();
        System.out.println("StringBuilder 拼接耗時(shí): " + (end - start) + "ms");
    }
}

典型輸出結(jié)果(不同機(jī)器配置有差異,但趨勢(shì)一致):

String 拼接耗時(shí): 1500ms
StringBuffer 拼接耗時(shí): 3ms
StringBuilder 拼接耗時(shí): 1ms

結(jié)論

  1. String+ 操作在大量拼接時(shí)性能最差,差了幾個(gè)數(shù)量級(jí)。
  2. StringBuilder 通常比 StringBuffer 快(本例中快2-3倍),因?yàn)槭∪チ送介_(kāi)銷。

第四章:橫向?qū)Ρ扰c選型指南

為了讓你一目了然,這里將四個(gè)核心概念進(jìn)行橫向?qū)Ρ龋?/p>

特性charStringStringBuilderStringBuffer
類型原始數(shù)據(jù)類型
不可變性/不可變 (Immutable)可變 (Mutable)可變 (Mutable)
線程安全/線程安全 (通過(guò)不可變性)非線程安全線程安全 (通過(guò)synchronized)
底層存儲(chǔ)16位Unicode值byte[] (JDK 9+)byte[] (JDK 9+)byte[] (JDK 9+)
性能(修改操作)N/A極差(創(chuàng)建大量對(duì)象)最高中等(有同步開(kāi)銷)
適用場(chǎng)景存儲(chǔ)單個(gè)字符操作少的字符串、常量、作為鍵的HashMap單線程下大量字符串操作(如循環(huán)拼接)多線程下共享的字符串緩沖區(qū)

4.1 選型指南:到底該用誰(shuí)?

  1. 處理單個(gè)字符:毫無(wú)疑問(wèn),使用 char。
  2. 操作少量、不變的字符串:使用 String。例如配置項(xiàng)、常量、不經(jīng)常變化的文本。
  3. 單線程環(huán)境下,需要大量操作字符串內(nèi)容(拼接、刪除、修改):首選 StringBuilder。例如,在方法內(nèi)部構(gòu)建復(fù)雜的SQL語(yǔ)句、處理JSON字符串、日志組裝等。這是最常見(jiàn)的場(chǎng)景。
  4. 多線程環(huán)境下,多個(gè)線程需要操作同一個(gè)字符串緩沖區(qū):必須使用 StringBuffer 來(lái)保證數(shù)據(jù)同步和安全。例如,一個(gè)全局的日志緩沖區(qū),多個(gè)線程都要向其追加內(nèi)容。
  5. 字符串作為HashMap的鍵:必須使用 String,因?yàn)槠洳豢勺冃院驼_的 hashCode() 實(shí)現(xiàn)。

第五章:常見(jiàn)面試題深度剖析

1. 談?wù)勀銓?duì)String的理解,它為什么是不可變的?

:String的不可變性體現(xiàn)在:

  1. 類本身被 final 修飾,不可繼承,防止子類破壞。
  2. 底層存儲(chǔ)字符的 byte[] (或 char[]) 數(shù)組被 private final 修飾,引用不可變,且String類沒(méi)有提供任何可以修改該數(shù)組內(nèi)部元素的方法(如 setCharAt())。所有看似修改的操作,如 concat(), substring(), replace() 等,都是返回一個(gè)新的String對(duì)象。
    這種設(shè)計(jì)帶來(lái)了線程安全、字符串常量池的內(nèi)存復(fù)用、哈希值緩存等巨大優(yōu)勢(shì)。

2. String、StringBuilder、StringBuffer的區(qū)別?

:三者都是用來(lái)處理字符串的,主要區(qū)別如下:

  • 可變性String 是不可變類,操作后產(chǎn)生新對(duì)象。StringBuilderStringBuffer 是可變類,可以在原對(duì)象上修改。
  • 線程安全String 是線程安全的。StringBuffer 的方法使用了 synchronized 修飾,是線程安全的。StringBuilder 的方法沒(méi)有同步,是線程不安全的。
  • 性能:在單線程環(huán)境下,StringBuilder 的性能最好,因?yàn)樗鼪](méi)有同步開(kāi)銷。StringBuffer 次之。String 在進(jìn)行大量修改時(shí)性能最差。

3. String s = new String(“xyz”); 創(chuàng)建了幾個(gè)對(duì)象?

:這取決于“xyz”這個(gè)字符串常量是否已經(jīng)存在于字符串常量池中。

  • 如果常量池中已經(jīng)存在"xyz":那么只在堆中創(chuàng)建一個(gè) String 對(duì)象。答案是 1個(gè)
  • 如果常量池中還沒(méi)有"xyz":JVM會(huì)先在常量池中創(chuàng)建字面量"xyz",然后再在堆中創(chuàng)建一個(gè) String 對(duì)象。答案是 2個(gè)。

4. 為什么用StringBuilder要好于用String的“+”拼接?

:雖然編譯器會(huì)將 + 優(yōu)化為 StringBuilder,但在循環(huán)等場(chǎng)景中,優(yōu)化是局部的。例如 for 循環(huán)內(nèi)的 +,每次循環(huán)都會(huì)在循環(huán)體內(nèi)生成一個(gè)新的 StringBuilder 對(duì)象,然后調(diào)用 append(),最后調(diào)用 toString() 返回。這會(huì)產(chǎn)生大量的中間對(duì)象,給垃圾回收帶來(lái)巨大壓力,嚴(yán)重影響性能。而手動(dòng)使用 StringBuilder 可以在循環(huán)外部創(chuàng)建一個(gè)對(duì)象,在整個(gè)循環(huán)中復(fù)用這一個(gè)對(duì)象進(jìn)行 append,極大地減少了對(duì)象創(chuàng)建,提升了效率。

總結(jié)

本文從微觀的 char 原始類型講起,深入剖析了其在Java中的Unicode特性和運(yùn)算規(guī)則。隨后,我們?cè)敿?xì)探討了 String 類的不可變性及其帶來(lái)的設(shè)計(jì)權(quán)衡,并由此引出為了解決性能問(wèn)題而誕生的 StringBuilderStringBuffer。通過(guò)對(duì)它們底層實(shí)現(xiàn)(繼承自 AbstractStringBuilder 的可變數(shù)組與擴(kuò)容機(jī)制)和線程安全性(synchronized 關(guān)鍵字的有無(wú))的對(duì)比,我們明確了各自的優(yōu)缺點(diǎn)和適用場(chǎng)景。

理解這些核心概念的區(qū)別與聯(lián)系,不僅僅是應(yīng)對(duì)面試,更是為了在日常開(kāi)發(fā)中做出正確的技術(shù)選型,寫出既高效又穩(wěn)健的代碼。希望這篇長(zhǎng)達(dá)數(shù)千字的詳解能幫助你徹底掌握J(rèn)ava中字符與字符串的奧秘。

到此這篇關(guān)于Java中的char、String、StringBuilder與StringBuffer全方面解析的文章就介紹到這了,更多相關(guān)Java char、String、StringBuilder與StringBuffer內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java泛型之協(xié)變與逆變及extends與super選擇

    Java泛型之協(xié)變與逆變及extends與super選擇

    這篇文章主要介紹了Java泛型之協(xié)變與逆變及extends與super選擇,文章圍繞主題內(nèi)容展開(kāi)詳細(xì)內(nèi)容介紹,需要的小伙伴可以參考一下
    2022-05-05
  • Java將Word文檔轉(zhuǎn)換為PDF文件的幾種常用方法總結(jié)

    Java將Word文檔轉(zhuǎn)換為PDF文件的幾種常用方法總結(jié)

    這篇文章主要介紹了Java將Word文檔轉(zhuǎn)換為PDF文件的四種常用方法,分別使用ApachePOI+iText、Aspose.Words?for?Java、Docx4j和JODConverter,這些庫(kù)各有優(yōu)點(diǎn),但在使用時(shí)需要注意庫(kù)與Java環(huán)境的兼容性、安裝所需依賴、轉(zhuǎn)換速度和資源消耗,需要的朋友可以參考下
    2024-10-10
  • SpringBoot異步Async使用Future與CompletableFuture區(qū)別小結(jié)

    SpringBoot異步Async使用Future與CompletableFuture區(qū)別小結(jié)

    本文主要介紹了SpringBoot異步Async使用Future與CompletableFuture區(qū)別小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • java讀取csv文件示例分享(java解析csv文件)

    java讀取csv文件示例分享(java解析csv文件)

    這篇文章主要介紹了java讀取csv文件示例,這個(gè)java解析csv文件的例子很簡(jiǎn)單,下面直接上代碼,大家參考使用吧
    2014-03-03
  • SpringBoot集成E-mail發(fā)送各種類型郵件

    SpringBoot集成E-mail發(fā)送各種類型郵件

    這篇文章主要為大家詳細(xì)介紹了SpringBoot集成E-mail發(fā)送各種類型郵件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • java實(shí)現(xiàn)分段讀取文件并通過(guò)HTTP上傳的方法

    java實(shí)現(xiàn)分段讀取文件并通過(guò)HTTP上傳的方法

    這篇文章主要介紹了java實(shí)現(xiàn)分段讀取文件并通過(guò)HTTP上傳的方法,實(shí)例分析了java分段讀取文件及使用http實(shí)現(xiàn)文件傳輸?shù)南嚓P(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • 基于Java和FFmpeg實(shí)現(xiàn)視頻壓縮和剪輯功能

    基于Java和FFmpeg實(shí)現(xiàn)視頻壓縮和剪輯功能

    在視頻處理開(kāi)發(fā)中,壓縮和剪輯是常見(jiàn)的需求,本文將介紹如何使用 Java 結(jié)合 FFmpeg 實(shí)現(xiàn)視頻壓縮和剪輯功能,同時(shí)去除數(shù)據(jù)庫(kù)操作,僅專注于視頻處理,需要的朋友可以參考下
    2025-08-08
  • Java設(shè)計(jì)模式單例模式(Singleton)用法解析

    Java設(shè)計(jì)模式單例模式(Singleton)用法解析

    這篇文章主要介紹了Java設(shè)計(jì)模式單例模式(Singleton)用法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • 淺析Spring的事務(wù)實(shí)現(xiàn)原理

    淺析Spring的事務(wù)實(shí)現(xiàn)原理

    這篇文章主要為大家詳細(xì)介紹了Spring中事務(wù)實(shí)現(xiàn)的原理,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Spring有一定的幫助,需要的可以參考一下
    2022-11-11
  • Spring?Security如何為用戶示例添加角色詳解

    Spring?Security如何為用戶示例添加角色詳解

    目前我正在用Java開(kāi)發(fā)一個(gè)基于Spring Boot的web應(yīng)用程序,下面這篇文章主要給大家介紹了關(guān)于Spring?Security如何為用戶示例添加角色的相關(guān)資料,需要的朋友可以參考下
    2022-10-10

最新評(píng)論

建昌县| 喀喇沁旗| 交口县| 体育| 龙泉市| 丹江口市| 格尔木市| 安义县| 井研县| 潞西市| 浑源县| 台中市| 诸城市| 朔州市| 平遥县| 水富县| 鞍山市| 澳门| 崇文区| 五台县| 佛坪县| 马公市| 深泽县| 长沙市| 永新县| 丁青县| 合川市| 清流县| 东海县| 忻州市| 东明县| 齐齐哈尔市| 盐边县| 鲜城| 乳山市| 西林县| 淮滨县| 共和县| 深圳市| 金塔县| 那坡县|