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

Java字符串常量池(String Constant Pool)原理、實(shí)現(xiàn)全解析

 更新時(shí)間:2025年12月19日 10:09:41   作者:Han.miracle  
本文詳細(xì)介紹了Java中的字符串常量池(String Constant Pool),包括其底層原理、存儲(chǔ)位置、創(chuàng)建機(jī)制、地址比較、intern方法以及常見問題,字符串常量池通過復(fù)用相同內(nèi)容的字符串對(duì)象,減少內(nèi)存開銷,提升性能,感興趣的朋友跟隨小編一起看看吧

字符串常量池(String Constant Pool)

字符串常量池是 Java 中用于優(yōu)化字符串內(nèi)存使用的核心機(jī)制,屬于 JVM 運(yùn)行時(shí)數(shù)據(jù)區(qū)的重要組成部分。其本質(zhì)是一個(gè)字符串駐留池(String Intern Pool),核心目標(biāo)是復(fù)用相同內(nèi)容的字符串對(duì)象,減少內(nèi)存開銷,提升性能。下面從底層原理、JVM 存儲(chǔ)位置、創(chuàng)建機(jī)制、地址比較、intern 方法、常見問題等維度,全面解析字符串常量池的所有內(nèi)容。

一、字符串常量池的底層本質(zhì)與設(shè)計(jì)初衷

1. 設(shè)計(jì)初衷:解決字符串的內(nèi)存浪費(fèi)問題

字符串是 Java 中最常用的對(duì)象之一,若每次創(chuàng)建相同內(nèi)容的字符串都新建對(duì)象,會(huì)導(dǎo)致大量重復(fù)對(duì)象占用內(nèi)存。例如:

// 若沒有常量池,會(huì)創(chuàng)建1000個(gè)內(nèi)容為"hello"的字符串對(duì)象
for (int i = 0; i < 1000; i++) {
    String s = "hello";
}

字符串常量池通過 **“駐留(Intern)” 機(jī)制 **,讓相同內(nèi)容的字符串僅保留一份副本,所有指向該內(nèi)容的字符串引用都指向這個(gè)副本,從而節(jié)省內(nèi)存。

2. 本質(zhì):一個(gè)哈希表(HashTable)

字符串常量池的底層實(shí)現(xiàn)是一個(gè)固定大小的哈希表(JDK1.7+),默認(rèn)容量為 1009(可通過 JVM 參數(shù)-XX:StringTableSize調(diào)整,JDK1.8 后默認(rèn)是 60013)。

  • 哈希表的key:字符串的內(nèi)容(字符序列)。
  • 哈希表的value:字符串對(duì)象的引用(JDK1.7+)或字符串對(duì)象本身(JDK1.6 及以前)。
  • 哈希表的作用:快速查找是否存在相同內(nèi)容的字符串,時(shí)間復(fù)雜度接近 O (1)。

二、字符串常量池的存儲(chǔ)位置(JDK 版本差異)

字符串常量池的存儲(chǔ)位置在不同 JDK 版本中存在重大變化,這是理解其機(jī)制的關(guān)鍵:

JDK 版本存儲(chǔ)位置存儲(chǔ)內(nèi)容關(guān)鍵說明
JDK1.6 及以前方法區(qū)(永久代,PermGen)字符串對(duì)象本身(字符數(shù)組 + 屬性)永久代內(nèi)存空間有限,容易出現(xiàn)OutOfMemoryError: PermGen space。
JDK1.7+堆內(nèi)存(Heap)字符串對(duì)象的引用(指向堆中的字符串對(duì)象)① 常量池從永久代移到堆,解決永久代內(nèi)存限制;② 存儲(chǔ)的是引用,而非對(duì)象本身,更節(jié)省內(nèi)存。
JDK1.8+堆內(nèi)存(Heap)字符串對(duì)象的引用JDK1.8 移除永久代,方法區(qū)改為元空間(Metaspace),常量池仍在堆中。

關(guān)鍵差異示例(JDK1.6 vs JDK1.7+)

String s = new String("abc");
// JDK1.6:常量池在永久代,存儲(chǔ)"abc"對(duì)象;堆中存儲(chǔ)另一個(gè)"abc"對(duì)象,s指向堆對(duì)象。
// JDK1.7+:常量池在堆中,存儲(chǔ)堆中"abc"對(duì)象的引用;堆中有一個(gè)"abc"對(duì)象(字面量),s指向堆中新建的另一個(gè)"abc"對(duì)象。

三、字符串的創(chuàng)建方式與常量池的交互

字符串的創(chuàng)建方式直接決定了其與常量池的交互邏輯,也是判斷 “地址是否相同” 的核心依據(jù)。

場(chǎng)景 1:直接使用字符串字面量創(chuàng)建(String s = "abc")

這是最常見的方式,完全依賴常量池的駐留機(jī)制。

執(zhí)行流程(JDK1.7+):
  1. JVM 首先檢查字符串常量池的哈希表,是否存在鍵為 “abc” 的條目。
  2. 若不存在
    • 堆內(nèi)存中創(chuàng)建一個(gè)字符串對(duì)象(內(nèi)容為 “abc”)。
    • 將該對(duì)象的引用存入字符串常量池的哈希表中(key=“abc”,value = 對(duì)象引用)。
    • 將引用變量s指向堆中的這個(gè)字符串對(duì)象。
  3. 若存在
    • 直接從常量池的哈希表中取出 “abc” 對(duì)應(yīng)的對(duì)象引用。
    • 將引用變量s指向該引用對(duì)應(yīng)的堆對(duì)象。
代碼示例:
String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2); // true(指向同一個(gè)堆對(duì)象)
System.out.println(s1.equals(s2)); // true(內(nèi)容相同)

場(chǎng)景 2:使用new String("內(nèi)容")創(chuàng)建

這種方式會(huì)創(chuàng)建至少一個(gè)、最多兩個(gè)字符串對(duì)象,是最容易產(chǎn)生內(nèi)存浪費(fèi)的方式。

執(zhí)行流程(JDK1.7+):
  1. 處理字符串字面量"abc":JVM 檢查常量池,若沒有則在堆中創(chuàng)建 “abc” 對(duì)象,并將引用存入常量池(這是第一個(gè)對(duì)象)。
  2. 執(zhí)行new String("abc"):在堆內(nèi)存中新建一個(gè)獨(dú)立的字符串對(duì)象(這是第二個(gè)對(duì)象),該對(duì)象的字符數(shù)組與常量池中的 “abc” 對(duì)象共享(JDK1.7 + 優(yōu)化,字符數(shù)組存儲(chǔ)在堆中,復(fù)用字符數(shù)組以節(jié)省內(nèi)存)。
  3. 引用變量s指向第二步新建的堆對(duì)象。
代碼示例:
String s1 = "abc"; // 常量池存引用,s1指向堆中的"abc"對(duì)象
String s2 = new String("abc"); // 堆中新建對(duì)象,s2指向該對(duì)象
String s3 = new String("abc"); // 堆中再新建對(duì)象,s3指向該對(duì)象
System.out.println(s1 == s2); // false(指向不同堆對(duì)象)
System.out.println(s2 == s3); // false(指向不同堆對(duì)象)
System.out.println(s1.equals(s2)); // true(內(nèi)容相同)
System.out.println(s2.intern() == s1); // true(intern()返回常量池引用)
關(guān)鍵:new String("abc")創(chuàng)建的對(duì)象數(shù)量
  • 最少 1 個(gè):若常量池中已存在 “abc” 的引用,則僅在堆中創(chuàng)建一個(gè)新對(duì)象。
  • 最多 2 個(gè):若常量池中不存在 “abc” 的引用,則先在堆中創(chuàng)建 “abc” 對(duì)象(供常量池引用),再在堆中創(chuàng)建一個(gè)新對(duì)象(供s引用)。

場(chǎng)景 3:字符串拼接(編譯期常量拼接 vs 運(yùn)行期拼接)

字符串拼接的結(jié)果是否指向常量池對(duì)象,取決于拼接的是常量還是變量

子場(chǎng)景 3.1:編譯期常量拼接(字面量 /final常量拼接)

特征:拼接的所有部分都是編譯期就能確定值的常量(字符串字面量、final字符串常量、基本類型常量)。原理:Java 編譯器會(huì)對(duì)這種拼接進(jìn)行編譯期優(yōu)化,直接將拼接結(jié)果作為一個(gè)字符串字面量存入常量池,運(yùn)行時(shí)不再執(zhí)行拼接操作。

代碼示例:
// 示例1:字面量拼接
String s1 = "abc";
String s2 = "ab" + "c"; // 編譯期優(yōu)化為"abc"
String s3 = "a" + "b" + "c"; // 編譯期優(yōu)化為"abc"
System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // true
// 示例2:final常量拼接
final String str1 = "ab"; // final常量,編譯期確定值
final int num = 123; // 基本類型常量
String s4 = str1 + "c"; // 編譯期優(yōu)化為"abc"
String s5 = "num" + num; // 編譯期優(yōu)化為"num123"
System.out.println(s1 == s4); // true
System.out.println("num123" == s5); // true
子場(chǎng)景 3.2:運(yùn)行期拼接(變量拼接)

特征:拼接的部分包含運(yùn)行期才能確定值的變量(非final字符串變量、對(duì)象引用等)。原理:這種拼接會(huì)在運(yùn)行期通過StringBuilderappend()方法拼接,再調(diào)用toString()方法生成新的字符串對(duì)象,該對(duì)象是堆中的新對(duì)象,與常量池?zé)o關(guān)。

代碼示例:
String s1 = "abc";
String s2 = "ab";
String s3 = s2 + "c"; // 運(yùn)行期拼接,底層用StringBuilder實(shí)現(xiàn)
String s4 = new String("ab") + new String("c"); // 運(yùn)行期拼接,堆新對(duì)象
System.out.println(s1 == s3); // false(s3指向堆新對(duì)象)
System.out.println(s1 == s4); // false(s4指向堆新對(duì)象)
System.out.println(s3 == s4); // false(兩個(gè)不同的堆對(duì)象)

場(chǎng)景 4:使用String.intern()方法(手動(dòng)駐留字符串)

intern()是 String 類的 native 方法(底層由 C/C++ 實(shí)現(xiàn)),作用是將字符串對(duì)象的內(nèi)容駐留到常量池,并返回常量池中的引用。這是手動(dòng)控制字符串常量池的核心方法。

// 案例1:new String() + intern()
String s1 = "abc";
String s2 = new String("abc").intern();
System.out.println(s1 == s2); // true(s2指向常量池中的對(duì)象)
// 案例2:運(yùn)行期拼接 + intern()
String s3 = "ab";
String s4 = s3 + "c"; // 堆中新對(duì)象
String s5 = s4.intern(); // 將s4的內(nèi)容"abc"加入常量池(已存在,返回引用)
System.out.println(s1 == s5); // true
System.out.println(s1 == s4); // false(s4還是堆中的對(duì)象)
        // 案例3:new String() + intern()
        String s1 = "abc";
        String s2 = new String("abc").intern();
        System.out.println(s1 == s2); // true(s2指向常量池中的對(duì)象)
        // 案例4:運(yùn)行期拼接 + intern()
        String s3 = "ab";
        String s4 = (s3 + "c").intern(); // 修正:補(bǔ)充intern()的括號(hào)
        System.out.println(s4 == s1); // 結(jié)果:true
    }
}

原理

  1. 調(diào)用intern()時(shí),JVM 檢查常量池:
    • 若常量池中已有該內(nèi)容的字符串,直接返回常量池中的引用。
    • 若沒有,將當(dāng)前字符串的內(nèi)容加入常量池(JDK1.7 + 是將堆中對(duì)象的引用存入常量池,JDK1.6 是復(fù)制對(duì)象到常量池),并返回常量池中的引用。結(jié)論intern()可以讓運(yùn)行期創(chuàng)建的字符串指向常量池的地址,實(shí)現(xiàn) “內(nèi)容相同則地址相同”。
執(zhí)行流程(JDK1.7+):
  1. 調(diào)用s.intern()時(shí),JVM 檢查字符串常量池的哈希表:
    • 若存在鍵為s內(nèi)容的條目:直接返回該條目對(duì)應(yīng)的引用。
    • 若不存在:將s引用存入常量池的哈希表(key=s 的內(nèi)容,value=s 的引用),并返回s的引用。
  2. JDK1.6 與 JDK1.7 + 的關(guān)鍵差異
    • JDK1.6:若常量池中不存在該字符串,會(huì)復(fù)制一份字符串對(duì)象到永久代的常量池,并返回永久代中對(duì)象的引用。
    • JDK1.7+:若常量池中不存在該字符串,會(huì)將堆中對(duì)象的引用存入常量池,而非復(fù)制對(duì)象,更節(jié)省內(nèi)存。
代碼示例(JDK1.7+):
// 示例1:new String() + intern()
String s1 = new String("abc"); // 堆對(duì)象1,常量池存"abc"的引用(指向堆中字面量對(duì)象)
String s2 = s1.intern(); // 常量池已有"abc"引用,返回該引用
System.out.println(s1 == s2); // false(s1指向堆對(duì)象1,s2指向常量池引用的對(duì)象)
// 示例2:運(yùn)行期拼接 + intern()
String s3 = new String("ab") + new String("c"); // 堆對(duì)象2,內(nèi)容為"abc",常量池?zé)o該引用
String s4 = s3.intern(); // 將s3的引用存入常量池,返回s3的引用
System.out.println(s3 == s4); // true(s4指向s3的堆對(duì)象2)
System.out.println(s4 == "abc"); // true("abc"指向常量池中的s3引用)
// 示例3:字面量 + intern()
String s5 = "hello";
String s6 = s5.intern();
System.out.println(s5 == s6); // true(常量池已有引用,直接返回)
應(yīng)用場(chǎng)景:海量字符串去重

當(dāng)處理大量重復(fù)字符串(如日志、數(shù)據(jù)庫(kù)數(shù)據(jù))時(shí),調(diào)用intern()方法可將重復(fù)字符串的引用指向常量池,大幅減少內(nèi)存占用。例如:

// 假設(shè)有100萬個(gè)內(nèi)容為"user_123"的字符串
String s = new String("user_123").intern();
// 后續(xù)所有"user_123"的字符串都調(diào)用intern(),則僅占用一份內(nèi)存

四、字符串常量池的地址比較:核心規(guī)則

Java 中判斷地址是否相同用==(比較引用),判斷內(nèi)容是否相同用equals()(比較字符序列)。結(jié)合常量池的機(jī)制,地址比較的核心規(guī)則如下:

字符串創(chuàng)建方式內(nèi)容相同時(shí),地址是否相同(==底層原因
字符串字面量("abc"常量池自動(dòng)復(fù)用相同內(nèi)容的引用。
new String("abc")每次new都創(chuàng)建堆新對(duì)象,與常量池引用無關(guān)。
編譯期常量拼接("ab"+"c"編譯器優(yōu)化為字面量,常量池復(fù)用引用。
運(yùn)行期變量拼接(s2+"c"底層StringBuilder生成堆新對(duì)象。
new String("abc").intern()intern()返回常量池中的引用,與字面量引用相同。
運(yùn)行期拼接 + intern()是(JDK1.7+)intern()將堆對(duì)象引用存入常量池,后續(xù)字面量指向該引用。

五、字符串常量池的常見問題與誤區(qū)

誤區(qū) 1:“字符串常量池存儲(chǔ)的是字符串對(duì)象”

糾正:JDK1.7 + 常量池存儲(chǔ)的是字符串對(duì)象的引用,而非對(duì)象本身;JDK1.6 及以前存儲(chǔ)的是對(duì)象本身。

  • 原因:JDK1.7 + 將常量池移到堆中,存儲(chǔ)引用可避免復(fù)制對(duì)象,節(jié)省內(nèi)存。

誤區(qū) 2:“String s = new String("abc")創(chuàng)建了一個(gè)對(duì)象”

糾正:最多創(chuàng)建兩個(gè)對(duì)象(常量池的字面量對(duì)象 + 堆的新對(duì)象),最少創(chuàng)建一個(gè)對(duì)象(常量池已有字面量,僅堆新對(duì)象)。

誤區(qū) 3:“intern()方法一定能節(jié)省內(nèi)存”

糾正intern()的哈希表是固定大小的,若大量調(diào)用intern()存儲(chǔ)不同內(nèi)容的字符串,會(huì)導(dǎo)致哈希表沖突,性能下降(從 O (1) 變?yōu)?O (n))。因此:

  • 適合大量重復(fù)字符串的場(chǎng)景(如去重)。
  • 不適合大量唯一字符串的場(chǎng)景(如 UUID),會(huì)浪費(fèi)常量池空間,降低性能。

誤區(qū) 4:“字符串是不可變的,所以常量池中的字符串也不能變”

糾正:字符串的不可變是指字符數(shù)組被final修飾,且沒有提供修改字符的方法(如setCharAt()),但通過反射可以修改字符數(shù)組的內(nèi)容(不推薦)。例如:

String s = "abc";
// 通過反射修改字符數(shù)組
Field valueField = String.class.getDeclaredField("value");
valueField.setAccessible(true);
char[] value = (char[]) valueField.get(s);
value[0] = 'x';
System.out.println(s); // 輸出:xbc
System.out.println("abc"); // 輸出:xbc(常量池中的引用指向同一個(gè)對(duì)象,因此也被修改)

注意:這種操作會(huì)破壞常量池的駐留機(jī)制,導(dǎo)致所有指向該字符串的引用都被修改,屬于高危操作,禁止在生產(chǎn)環(huán)境使用。

誤區(qū) 5:“空字符串""也在常量池中”

糾正:空字符串""是一個(gè)合法的字符串字面量,會(huì)被駐留到常量池中。例如:

String s1 = "";
String s2 = "";
System.out.println(s1 == s2); // true(常量池復(fù)用引用)

六、字符串常量池的 JVM 參數(shù)調(diào)優(yōu)

1. 調(diào)整字符串常量池的哈希表大小

JVM 參數(shù):-XX:StringTableSize=<size>

  • JDK1.6:默認(rèn)大小 1009,最大可設(shè)為 65535。
  • JDK1.7+:默認(rèn)大小 60013(JDK1.8),可設(shè)為更大的質(zhì)數(shù)(如 1000003),減少哈希沖突。
  • 適用場(chǎng)景:當(dāng)系統(tǒng)中存在大量intern()調(diào)用時(shí),增大哈希表大小可提升查找性能。

2. 開啟字符串去重(JDK1.8u20+)

JVM 參數(shù):-XX:+UseStringDeduplication

  • 作用:在 G1 垃圾收集器中,自動(dòng)檢測(cè)堆中重復(fù)的字符串對(duì)象,讓它們共享同一個(gè)字符數(shù)組,進(jìn)一步節(jié)省內(nèi)存。
  • 區(qū)別:與常量池的駐留機(jī)制不同,該參數(shù)是在堆中對(duì)字符串對(duì)象的字符數(shù)組去重,而常量池是對(duì)引用的駐留。

七、總結(jié)

字符串常量池是 Java 優(yōu)化字符串內(nèi)存的核心機(jī)制,其關(guān)鍵要點(diǎn)可歸納為:

  1. 存儲(chǔ)位置:JDK1.6 在永久代,JDK1.7 + 在堆中。
  2. 底層實(shí)現(xiàn):哈希表,存儲(chǔ)字符串內(nèi)容與引用的映射(JDK1.7+)。
  3. 核心機(jī)制:駐留(Intern),相同內(nèi)容的字符串僅保留一份引用。
  4. 創(chuàng)建方式:字面量創(chuàng)建復(fù)用常量池,new String()創(chuàng)建新對(duì)象,拼接分為編譯期和運(yùn)行期。
  5. intern 方法:手動(dòng)將字符串駐留到常量池,JDK1.7 + 存儲(chǔ)引用,JDK1.6 存儲(chǔ)對(duì)象。
  6. 地址比較==比較引用,equals()比較內(nèi)容,常量池中的字符串引用相同。

理解字符串常量池的機(jī)制,不僅能避免內(nèi)存浪費(fèi),還能在面試和生產(chǎn)環(huán)境中解決字符串相關(guān)的性能問題。

到此這篇關(guān)于Java字符串常量池(String Constant Pool)原理、實(shí)現(xiàn)全解析的文章就介紹到這了,更多相關(guān)java字符串常量池內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文學(xué)會(huì)Java運(yùn)算符的使用

    一文學(xué)會(huì)Java運(yùn)算符的使用

    計(jì)算機(jī)的最基本用途之一就是執(zhí)行數(shù)學(xué)運(yùn)算,作為一門計(jì)算機(jī)語(yǔ)言,Java也提供了一套豐富的運(yùn)算符來操縱變量,本篇通過示例詳細(xì)講解了Java中不同運(yùn)算符的使用,需要的朋友可以參考下
    2022-05-05
  • java  中ThreadLocal實(shí)例分析

    java 中ThreadLocal實(shí)例分析

    這篇文章主要介紹了java 中ThreadLocal實(shí)例分析的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • 淺談SpringMVC中的session用法及細(xì)節(jié)記錄

    淺談SpringMVC中的session用法及細(xì)節(jié)記錄

    下面小編就為大家?guī)硪黄獪\談SpringMVC中的session用法及細(xì)節(jié)記錄。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-05-05
  • java 流與 byte[] 的互轉(zhuǎn)操作

    java 流與 byte[] 的互轉(zhuǎn)操作

    這篇文章主要介紹了java 流與 byte[] 的互轉(zhuǎn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • SpringBoot使用@Async注解實(shí)現(xiàn)異步調(diào)用

    SpringBoot使用@Async注解實(shí)現(xiàn)異步調(diào)用

    這篇文章主要介紹了SpringBoot使用@Async注解實(shí)現(xiàn)異步調(diào)用,異步調(diào)用是相對(duì)于同步調(diào)用而言的,同步調(diào)用是指程序按預(yù)定順序一步步執(zhí)行,每一步必須等到上一步執(zhí)行完后才能執(zhí)行,異步調(diào)用則無需等待,程序執(zhí)行完即可執(zhí)行,可以減少程序執(zhí)行時(shí)間,需要的朋友可以參考下
    2023-10-10
  • java編程中自動(dòng)拆箱與自動(dòng)裝箱詳解

    java編程中自動(dòng)拆箱與自動(dòng)裝箱詳解

    這篇文章主要介紹了java編程中自動(dòng)拆箱與自動(dòng)裝箱詳解,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • Java定時(shí)器@Scheduled注解的使用方法

    Java定時(shí)器@Scheduled注解的使用方法

    這篇文章主要給大家介紹了關(guān)于Java定時(shí)器@Scheduled注解的使用方法,在Java中使用@Scheduled注解可以方便地實(shí)現(xiàn)定時(shí)任務(wù)的功能,文中介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • IDEA類和方法注釋模板設(shè)置(非常詳細(xì))

    IDEA類和方法注釋模板設(shè)置(非常詳細(xì))

    這篇文章主要介紹了IDEA類和方法注釋模板設(shè)置(非常詳細(xì)),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-08-08
  • Java替換字符串replace和replaceAll方法舉例詳解

    Java替換字符串replace和replaceAll方法舉例詳解

    這篇文章主要介紹了Java中替換字符串的幾種方法,包括String類的replace()、replaceAll()、replaceFirst()方法,以及StringBuilder和StringBuffer類的replace()方法,還提到了一些第三方庫(kù),如Hutool,它們提供了更豐富的字符串處理功能,需要的朋友可以參考下
    2025-02-02
  • String實(shí)例化及static final修飾符實(shí)現(xiàn)方法解析

    String實(shí)例化及static final修飾符實(shí)現(xiàn)方法解析

    這篇文章主要介紹了String實(shí)例化及static final修飾符實(shí)現(xiàn)方法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09

最新評(píng)論

抚顺县| 科技| 邢台市| 大庆市| 松桃| 开阳县| 巨野县| 瓦房店市| 东港市| 池州市| 兰考县| 苗栗县| 宜黄县| 来凤县| 离岛区| 锦州市| 宝鸡市| 沽源县| 铅山县| 东宁县| 大理市| 博湖县| 乐都县| 元谋县| 贵定县| 营山县| 永春县| 集贤县| 长治市| 互助| 阿鲁科尔沁旗| 金门县| 贵南县| 定南县| 锦屏县| 吴忠市| 武宣县| 华蓥市| 历史| 濉溪县| 海原县|