亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

java String的深入理解

 更新時(shí)間:2017年09月19日 15:33:43   投稿:lqh  
這篇文章主要介紹了java String的深入理解的相關(guān)資料,希望通過(guò)本文大家能理解String的用法,需要的朋友可以參考下

java String的深入理解

一、Java內(nèi)存模型 

按照官方的說(shuō)法:Java 虛擬機(jī)具有一個(gè)堆,堆是運(yùn)行時(shí)數(shù)據(jù)區(qū)域,所有類(lèi)實(shí)例和數(shù)組的內(nèi)存均從此處分配。    

JVM主要管理兩種類(lèi)型內(nèi)存:堆和非堆,堆內(nèi)存(Heap Memory)是在 Java 虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建,非堆內(nèi)存(Non-heap Memory)是在JVM堆之外的內(nèi)存。

簡(jiǎn)單來(lái)說(shuō),非堆包含方法區(qū)、JVM內(nèi)部處理或優(yōu)化所需的內(nèi)存(如 JITCompiler,Just-in-time Compiler,即時(shí)編譯后的代碼緩存)、每個(gè)類(lèi)結(jié)構(gòu)(如運(yùn)行時(shí)常數(shù)池、字段和方法數(shù)據(jù))以及方法和構(gòu)造方法的代碼。     

Java的堆是一個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū),類(lèi)的(對(duì)象從中分配空間。這些對(duì)象通過(guò)new、newarray、 anewarray和multianewarray等指令建立,它們不需要程序代碼來(lái)顯式的釋放。

堆是由垃圾回收來(lái)負(fù)責(zé)的,堆的優(yōu)勢(shì)是可以動(dòng)態(tài)地分配內(nèi)存大小,生存期也不必事先告訴編譯器,因?yàn)樗窃谶\(yùn)行時(shí)動(dòng)態(tài)分配內(nèi)存的,Java的垃圾收集器會(huì)自動(dòng)收走這些不再使用的數(shù)據(jù)。但缺點(diǎn)是,由于要在運(yùn)行時(shí)動(dòng)態(tài)分配內(nèi)存,存取速度較慢。   

棧的優(yōu)勢(shì)是,存取速度比堆要快,僅次于寄存器,棧數(shù)據(jù)可以共享。但缺點(diǎn)是,存在棧中的數(shù)據(jù)大小與生存期必須是確定的,缺乏靈活性。棧中主要存放一些基本類(lèi)型的變量數(shù)據(jù)(int, short, long, byte, float, double, boolean, char)和對(duì)象句柄(引用)。     

虛擬機(jī)必須為每個(gè)被裝載的類(lèi)型維護(hù)一個(gè)常量池。常量池就是該類(lèi)型所用到常量的一個(gè)有序集合,包括直接常量(string,integer和 floating point常量)和對(duì)其他類(lèi)型,字段和方法的符號(hào)引用。   

對(duì)于String常量,它的值是在常量池中的。而JVM中的常量池在內(nèi)存當(dāng)中是以表的形式存在的, 對(duì)于String類(lèi)型,有一張固定長(zhǎng)度的CONSTANT_String_info表用來(lái)存儲(chǔ)文字字符串值,注意:該表只存儲(chǔ)文字字符串值,不存儲(chǔ)符號(hào)引用。說(shuō)到這里,對(duì)常量池中的字符串值的存儲(chǔ)位置應(yīng)該有一個(gè)比較明了的理解了。在程序執(zhí)行的時(shí)候,常量池會(huì)儲(chǔ)存在Method Area,而不是堆中。常量池中保存著很多String對(duì)象; 并且可以被共享使用,因此它提高了效率 

二、案例解析

public static void main(String[] args) { 
    /** 
     * 情景一:字符串池 
     * JAVA虛擬機(jī)(JVM)中存在著一個(gè)字符串池,其中保存著很多String對(duì)象; 
     * 并且可以被共享使用,因此它提高了效率。 
     * 由于String類(lèi)是final的,它的值一經(jīng)創(chuàng)建就不可改變。 
     * 字符串池由String類(lèi)維護(hù),我們可以調(diào)用intern()方法來(lái)訪問(wèn)字符串池。 
     */ 
    String s1 = "abc";   
    //↑ 在字符串池創(chuàng)建了一個(gè)對(duì)象 
    String s2 = "abc";   
    //↑ 字符串pool已經(jīng)存在對(duì)象“abc”(共享),所以創(chuàng)建0個(gè)對(duì)象,累計(jì)創(chuàng)建一個(gè)對(duì)象 
    System.out.println("s1 == s2 : "+(s1==s2));  
    //↑ true 指向同一個(gè)對(duì)象, 
    System.out.println("s1.equals(s2) : " + (s1.equals(s2)));  
    //↑ true 值相等 
    //↑------------------------------------------------------over 
    /** 
     * 情景二:關(guān)于new String("") 
     * 
     */ 
    String s3 = new String("abc"); 
    //↑ 創(chuàng)建了兩個(gè)對(duì)象,一個(gè)存放在字符串池中,一個(gè)存在與堆區(qū)中; 
    //↑ 還有一個(gè)對(duì)象引用s3存放在棧中 
    String s4 = new String("abc"); 
    //↑ 字符串池中已經(jīng)存在“abc”對(duì)象,所以只在堆中創(chuàng)建了一個(gè)對(duì)象 
    System.out.println("s3 == s4 : "+(s3==s4)); 
    //↑false  s3和s4棧區(qū)的地址不同,指向堆區(qū)的不同地址; 
    System.out.println("s3.equals(s4) : "+(s3.equals(s4))); 
    //↑true s3和s4的值相同 
    System.out.println("s1 == s3 : "+(s1==s3)); 
    //↑false 存放的地區(qū)多不同,一個(gè)棧區(qū),一個(gè)堆區(qū) 
    System.out.println("s1.equals(s3) : "+(s1.equals(s3))); 
    //↑true 值相同 
    //↑------------------------------------------------------over 
    /** 
     * 情景三: 
     * 由于常量的值在編譯的時(shí)候就被確定(優(yōu)化)了。 
     * 在這里,"ab"和"cd"都是常量,因此變量str3的值在編譯時(shí)就可以確定。 
     * 這行代碼編譯后的效果等同于: String str3 = "abcd"; 
     */ 
    String str1 = "ab" + "cd"; //1個(gè)對(duì)象 
    String str11 = "abcd";  
    System.out.println("str1 = str11 : "+ (str1 == str11)); 
    //↑------------------------------------------------------over 
    /** 
     * 情景四: 
     * 局部變量str2,str3存儲(chǔ)的是存儲(chǔ)兩個(gè)拘留字符串對(duì)象(intern字符串對(duì)象)的地址。 
     * 
     * 第三行代碼原理(str2+str3): 
     * 運(yùn)行期JVM首先會(huì)在堆中創(chuàng)建一個(gè)StringBuilder類(lèi), 
     * 同時(shí)用str2指向的拘留字符串對(duì)象完成初始化, 
     * 然后調(diào)用append方法完成對(duì)str3所指向的拘留字符串的合并, 
     * 接著調(diào)用StringBuilder的toString()方法在堆中創(chuàng)建一個(gè)String對(duì)象, 
     * 最后將剛生成的String對(duì)象的堆地址存放在局部變量str3中。 
     * 
     * 而str5存儲(chǔ)的是字符串池中"abcd"所對(duì)應(yīng)的拘留字符串對(duì)象的地址。 
     * str4與str5地址當(dāng)然不一樣了。 
     * 
     * 內(nèi)存中實(shí)際上有五個(gè)字符串對(duì)象: 
     *    三個(gè)拘留字符串對(duì)象、一個(gè)String對(duì)象和一個(gè)StringBuilder對(duì)象。 
     */ 
    String str2 = "ab"; //1個(gè)對(duì)象 
    String str3 = "cd"; //1個(gè)對(duì)象                     
    String str4 = str2+str3;                    
    String str5 = "abcd";  
    System.out.println("str4 = str5 : " + (str4==str5)); // false 
    //↑------------------------------------------------------over 
    /** 
     * 情景五: 
     * JAVA編譯器對(duì)string + 基本類(lèi)型/常量 是當(dāng)成常量表達(dá)式直接求值來(lái)優(yōu)化的。 
     * 運(yùn)行期的兩個(gè)string相加,會(huì)產(chǎn)生新的對(duì)象的,存儲(chǔ)在堆(heap)中 
     */ 
    String str6 = "b"; 
    String str7 = "a" + str6; 
    String str67 = "ab"; 
    System.out.println("str7 = str67 : "+ (str7 == str67)); 
    //↑str6為變量,在運(yùn)行期才會(huì)被解析。 
    final String str8 = "b"; 
    String str9 = "a" + str8; 
    String str89 = "ab"; 
    System.out.println("str9 = str89 : "+ (str9 == str89)); 
    //↑str8為常量變量,編譯期會(huì)被優(yōu)化 
    //↑------------------------------------------------------over 
  }

總結(jié):

1.String類(lèi)初始化后是不可變的(immutable)

這一說(shuō)又要說(shuō)很多,大家只要知道String的實(shí)例一旦生成就不會(huì)再改變了,比如說(shuō):String str=”kv”+”ill”+” “+”ans”; 就是有4個(gè)字符串常量,首先”kv”和”ill”生成了”kvill”存在內(nèi)存中,然后”kvill”又和” ” 生成 “kvill “存在內(nèi)存中,最后又和生成了”kvill ans”;并把這個(gè)字符串的地址賦給了str,就是因?yàn)镾tring的”不可變”產(chǎn)生了很多臨時(shí)變量,這也就是為什么建議用StringBuffer的原 因了,因?yàn)镾tringBuffer是可改變的。

   下面是一些String相關(guān)的常見(jiàn)問(wèn)題:

String中的final用法和理解 
final StringBuffer a = new StringBuffer(“111”); 
final StringBuffer b = new StringBuffer(“222”); 
a=b;//此句編譯不通過(guò) final StringBuffer a = new StringBuffer(“111”); 
a.append(“222”);// 編譯通過(guò)

可見(jiàn),final只對(duì)引用的”值”(即內(nèi)存地址)有效,它迫使引用只能指向初始指向的那個(gè)對(duì)象,改變它的指向會(huì)導(dǎo)致編譯期錯(cuò)誤。至于它所指向的對(duì)象的變化,final是不負(fù)責(zé)的。

2.代碼中的字符串常量在編譯的過(guò)程中收集并放在class文件的常量區(qū)中,如”123”、”123”+”456”等,含有變量的表達(dá)式不會(huì)收錄,如”123”+a。

3.JVM在加載類(lèi)的時(shí)候,根據(jù)常量區(qū)中的字符串生成常量池,每個(gè)字符序列如”123”會(huì)生成一個(gè)實(shí)例放在常量池里,這個(gè)實(shí)例是不在堆里的,也不會(huì)被GC,這個(gè)實(shí)例的value屬性從源碼的構(gòu)造函數(shù)看應(yīng)該是用new創(chuàng)建數(shù)組置入123的,所以按我的理解此時(shí)value存放的字符數(shù)組地址是在堆里,如果有誤的話歡迎大家指正。

4.使用String不一定創(chuàng)建對(duì)象

在執(zhí)行到雙引號(hào)包含字符串的語(yǔ)句時(shí),如String a = “123”,JVM會(huì)先到常量池里查找,如果有的話返回常量池里的這個(gè)實(shí)例的引用,否則的話創(chuàng)建一個(gè)新實(shí)例并置入常量池里。如果是 String a = “123” + b (假設(shè)b是”456”),前半部分”123”還是走常量池的路線,但是這個(gè)+操作符其實(shí)是轉(zhuǎn)換成[SringBuffer].Appad()來(lái)實(shí)現(xiàn)的,所以最終a得到是一個(gè)新的實(shí)例引用,而且a的value存放的是一個(gè)新申請(qǐng)的字符數(shù)組內(nèi)存空間的地址(存放著”123456”),而此時(shí)”123456”在常量池中是未必存在的。

要注意: 我們?cè)谑褂弥T如String str = “abc”;的格式定義類(lèi)時(shí),總是想當(dāng)然地認(rèn)為,創(chuàng)建了String類(lèi)的對(duì)象str。擔(dān)心陷阱!對(duì)象可能并沒(méi)有被創(chuàng)建!而可能只是指向一個(gè)先前已經(jīng)創(chuàng)建的對(duì)象。只有通過(guò)new()方法才能保證每次都創(chuàng)建一個(gè)新的對(duì)象

5.使用new String,一定創(chuàng)建對(duì)象

在執(zhí)行String a = new String(“123”)的時(shí)候,首先走常量池的路線取到一個(gè)實(shí)例的引用,然后在堆上創(chuàng)建一個(gè)新的String實(shí)例,走以下構(gòu)造函數(shù)給value屬性賦值,然后把實(shí)例引用賦值給a:

public String(String original) {
  int size = original.count;
  char[] originalValue = original.value;
  char[] v;
   if (originalValue.length > size) {
     // The array representing the String is bigger than the new
     // String itself. Perhaps this constructor is being called
     // in order to trim the baggage, so make a copy of the array.
      int off = original.offset;
      v = Arrays.copyOfRange(originalValue, off, off+size);
   } else {
     // The array representing the String is the same
     // size as the String, so no point in making a copy.
    v = originalValue;
   }
  this.offset = 0;
  this.count = size;
  this.value = v;
  }

從中我們可以看到,雖然是新創(chuàng)建了一個(gè)String的實(shí)例,但是value是等于常量池中的實(shí)例的value,即是說(shuō)沒(méi)有new一個(gè)新的字符數(shù)組來(lái)存放”123”。

如果是String a = new String(“123”+b)的情況,首先看回第4點(diǎn),”123”+b得到一個(gè)實(shí)例后,再按上面的構(gòu)造函數(shù)執(zhí)行。

6.String.intern()

String對(duì)象的實(shí)例調(diào)用intern方法后,可以讓JVM檢查常量池,如果沒(méi)有實(shí)例的value屬性對(duì)應(yīng)的字符串序列比如”123”(注意是檢查字符串序列而不是檢查實(shí)例本身),就將本實(shí)例放入常量池,如果有當(dāng)前實(shí)例的value屬性對(duì)應(yīng)的字符串序列”123”在常量池中存在,則返回常量池中”123”對(duì)應(yīng)的實(shí)例的引用而不是當(dāng)前實(shí)例的引用,即使當(dāng)前實(shí)例的value也是”123”。

public native String intern();

存在于.class文件中的常量池,在運(yùn)行期被JVM裝載,并且可以擴(kuò)充。String的 intern()方法就是擴(kuò)充常量池的 一個(gè)方法;當(dāng)一個(gè)String實(shí)例str調(diào)用intern()方法時(shí),Java 查找常量池中 是否有相同Unicode的字符串常量,如果有,則返回其的引用,如果沒(méi)有,則在常 量池中增加一個(gè)Unicode等于str的字符串并返回它的引用;看示例就清楚了

/**
 * Java學(xué)習(xí)交流QQ群:589809992 我們一起學(xué)Java!
 */
public static void main(String[] args) {
    String s0 = "kvill"; 
    String s1 = new String("kvill"); 
    String s2 = new String("kvill"); 
    System.out.println( s0 == s1 ); //false
    System.out.println( "**********" ); 
    s1.intern(); //雖然執(zhí)行了s1.intern(),但它的返回值沒(méi)有賦給s1
    s2 = s2.intern(); //把常量池中"kvill"的引用賦給s2 
    System.out.println( s0 == s1); //flase
    System.out.println( s0 == s1.intern() ); //true//說(shuō)明s1.intern()返回的是常量池中"kvill"的引用
    System.out.println( s0 == s2 ); //true
  }

最后我再破除一個(gè)錯(cuò)誤的理解:有人說(shuō),“使用 String.intern() 方法則可以將一個(gè) String 類(lèi)的保存到一個(gè)全局 String 表中 ,如果具有相同值的 Unicode 字符串已經(jīng)在這個(gè)表中,那么該方法返回表中已有字符串的地址,如果在表中沒(méi)有相同值的字符串,則將自己的地址注冊(cè)到表中”如果我把他說(shuō)的這個(gè)全局的 String 表理解為常量池的話,他的最后一句話,”如果在表中沒(méi)有相同值的字符串,則將自己的地址注冊(cè)到表中”是錯(cuò)的:

public static void main(String[] args) {    
    String s1 = new String("kvill"); 
    String s2 = s1.intern(); 
    System.out.println( s1 == s1.intern() ); //false
    System.out.println( s1 + " " + s2 ); //kvill kvill
    System.out.println( s2 == s1.intern() ); //true
  }

在這個(gè)類(lèi)中我們沒(méi)有聲名一個(gè)”kvill”常量,所以常量池中一開(kāi)始是沒(méi)有”kvill”的,當(dāng)我們調(diào)用s1.intern()后就在常量池中新添加了一 個(gè)”kvill”常量,原來(lái)的不在常量池中的”kvill”仍然存在,也就不是“將自己的地址注冊(cè)到常量池中”了。

   s1==s1.intern() 為false說(shuō)明原來(lái)的”kvill”仍然存在;s2現(xiàn)在為常量池中”kvill”的地址,所以有s2==s1.intern()為true。

StringBuffer與StringBuilder的區(qū)別,它們的應(yīng)用場(chǎng)景是什么?

jdk的實(shí)現(xiàn)中StringBuffer與StringBuilder都繼承自AbstractStringBuilder,對(duì)于多線程的安全與非安全看到StringBuffer中方法前面的一堆synchronized就大概了解了。

這里隨便講講AbstractStringBuilder的實(shí)現(xiàn)原理:我們知道使用StringBuffer等無(wú)非就是為了提高java中字符串連接的效率,因?yàn)橹苯邮褂?進(jìn)行字符串連接的話,jvm會(huì)創(chuàng)建多個(gè)String對(duì)象,因此造成一定的開(kāi)銷(xiāo)。AbstractStringBuilder中采用一個(gè)char數(shù)組來(lái)保存需要append的字符串,char數(shù)組有一個(gè)初始大小,當(dāng)append的字符串長(zhǎng)度超過(guò)當(dāng)前char數(shù)組容量時(shí),則對(duì)char數(shù)組進(jìn)行動(dòng)態(tài)擴(kuò)展,也即重新申請(qǐng)一段更大的內(nèi)存空間,然后將當(dāng)前char數(shù)組拷貝到新的位置,因?yàn)橹匦路峙鋬?nèi)存并拷貝的開(kāi)銷(xiāo)比較大,所以每次重新申請(qǐng)內(nèi)存空間都是采用申請(qǐng)大于當(dāng)前需要的內(nèi)存空間的方式,這里是2倍,

StringBuffer 始于 JDK 1.0

StringBuilder 始于 JDK 1.5

從 JDK 1.5 開(kāi)始,帶有字符串變量的連接操作(+),JVM 內(nèi)部采用的是
StringBuilder 來(lái)實(shí)現(xiàn)的,而之前這個(gè)操作是采用 StringBuffer 實(shí)現(xiàn)的。

我們通過(guò)一個(gè)簡(jiǎn)單的程序來(lái)看其執(zhí)行的流程:

/**
 * Java學(xué)習(xí)交流QQ群:589809992 我們一起學(xué)Java!
 */
public class Buffer { 
   public static void main(String[] args) { 
      String s1 = "aaaaa"; 
      String s2 = "bbbbb"; 
      String r = null; 
      int i = 3694; 
      r = s1 + i + s2;  

      for(int j=0;i<10;j++){ 
        r+="23124"; 
      } 
   } 
}

使用命令javap -c Buffer查看其字節(jié)碼實(shí)現(xiàn):

將清單1和清單2對(duì)應(yīng)起來(lái)看,清單2的字節(jié)碼中l(wèi)dc指令即從常量池中加載“aaaaa”字符串到棧頂,istore_1將“aaaaa”存到變量1中,后面的一樣,sipush是將一個(gè)短整型常量值(-32768~32767)推送至棧頂,這里是常量“3694”。  

讓我們直接看到13,13~17是new了一個(gè)StringBuffer對(duì)象并調(diào)用其初始化方法,20 ~ 21則是先通過(guò)aload_1將變量1壓到棧頂,前面說(shuō)過(guò)變量1放的就是字符串常量“aaaaa”,接著通過(guò)指令invokevirtual調(diào)用StringBuffer的append方法將“aaaaa”拼接起來(lái),后續(xù)的24 ~ 30同理。最后在33調(diào)用StringBuffer的toString函數(shù)獲得String結(jié)果并通過(guò)astore存到變量3中。  

看到這里可能有人會(huì)說(shuō),“既然JVM內(nèi)部采用了StringBuffer來(lái)連接字符串了,那么我們自己就不用用StringBuffer,直接用”+“就行了吧!“。是么?當(dāng)然不是了。俗話說(shuō)”存在既有它的理由”,讓我們繼續(xù)看后面的循環(huán)對(duì)應(yīng)的字節(jié)碼。  

37~ 42都是進(jìn)入for循環(huán)前的一些準(zhǔn)備工作,37,38是將j置為1。44這里通過(guò)if_icmpge將j與10進(jìn)行比較,如果j大于10則直接跳轉(zhuǎn)到73,也即return語(yǔ)句退出函數(shù);否則進(jìn)入循環(huán),也即47~66的字節(jié)碼。這里我們只需看47到51就知道為什么我們要在代碼中自己使用StringBuffer來(lái)處理字符串的連接了,因?yàn)槊看螆?zhí)行“+”操作時(shí)jvm都要new一個(gè)StringBuffer對(duì)象來(lái)處理字符串的連接,這在涉及很多的字符串連接操作時(shí)開(kāi)銷(xiāo)會(huì)很大。

如有疑問(wèn)請(qǐng)留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

相關(guān)文章

  • 深入理解java1.8之supplier

    深入理解java1.8之supplier

    這篇文章主要介紹了深入理解java1.8之supplier,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • 利用Java中Calendar計(jì)算兩個(gè)日期之間的天數(shù)和周數(shù)

    利用Java中Calendar計(jì)算兩個(gè)日期之間的天數(shù)和周數(shù)

    Java 語(yǔ)言的Calendar(日歷),Date(日期),和DateFormat(日期格式)組成了Java標(biāo)準(zhǔn)的一個(gè)基本但是非常重要的部分。日期是商業(yè)邏輯計(jì)算一個(gè)關(guān)鍵的部分。下面這篇文章就給大家介紹了如何利用Java中Calendar計(jì)算兩個(gè)日期之間的天數(shù)和周數(shù),下面來(lái)一起看看吧。
    2016-12-12
  • ChatGPT介紹及Java?API調(diào)用

    ChatGPT介紹及Java?API調(diào)用

    本文主要介紹了ChatGPT介紹及Java?API調(diào)用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Springboot實(shí)現(xiàn)郵箱驗(yàn)證代碼實(shí)例

    Springboot實(shí)現(xiàn)郵箱驗(yàn)證代碼實(shí)例

    這篇文章主要介紹了Springboot實(shí)現(xiàn)郵箱驗(yàn)證代碼實(shí)例,在一些業(yè)務(wù)需求中我們經(jīng)常需要使用郵箱進(jìn)行驗(yàn)證碼的收取,本文通過(guò)簡(jiǎn)單的代碼實(shí)例來(lái)說(shuō)明,需要的朋友可以參考下
    2024-01-01
  • 詳解Spring cloud使用Ribbon進(jìn)行Restful請(qǐng)求

    詳解Spring cloud使用Ribbon進(jìn)行Restful請(qǐng)求

    這篇文章主要介紹了詳解Spring cloud使用Ribbon進(jìn)行Restful請(qǐng)求,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • SpringBoot多環(huán)境切換的靈活配置詳細(xì)教程

    SpringBoot多環(huán)境切換的靈活配置詳細(xì)教程

    在真實(shí)項(xiàng)目開(kāi)發(fā)的時(shí)候,一定會(huì)有多個(gè)環(huán)境,下面這篇文章主要給大家介紹了關(guān)于SpringBoot多環(huán)境切換靈活配置的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-04-04
  • Spring整合Struts2的兩種方法小結(jié)

    Spring整合Struts2的兩種方法小結(jié)

    下面小編就為大家?guī)?lái)一篇Spring整合Struts2的兩種方法小結(jié)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-07-07
  • Java中的clone方法詳解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java中的clone方法詳解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    clone顧名思義就是復(fù)制, 在Java語(yǔ)言中, clone方法被對(duì)象調(diào)用,所以會(huì)復(fù)制對(duì)象。下面通過(guò)本文給大家介紹java中的clone方法,感興趣的朋友一起看看吧
    2017-06-06
  • Java 關(guān)于時(shí)間復(fù)雜度和空間復(fù)雜度的深度刨析

    Java 關(guān)于時(shí)間復(fù)雜度和空間復(fù)雜度的深度刨析

    算法復(fù)雜度分為時(shí)間復(fù)雜度和空間復(fù)雜度。其作用: 時(shí)間復(fù)雜度是度量算法執(zhí)行的時(shí)間長(zhǎng)短;而空間復(fù)雜度是度量算法所需存儲(chǔ)空間的大小
    2021-11-11
  • 一文帶你入門(mén)SpringMVC的配置與使用

    一文帶你入門(mén)SpringMVC的配置與使用

    Spring MVC是Spring Framework的一部分,是基于Java實(shí)現(xiàn)MVC的輕量級(jí)Web框架。本文將通過(guò)一些簡(jiǎn)單示例帶大家掌握SpringMVC的配置與使用,感興趣的可以了解一下
    2022-11-11

最新評(píng)論