欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中泛型學(xué)習(xí)之細(xì)節(jié)篇

 更新時(shí)間:2022年02月16日 11:44:46   作者:湯圓  
泛型在java中有很重要的地位,在面向?qū)ο缶幊碳案鞣N設(shè)計(jì)模式中有非常廣泛的應(yīng)用,下面這篇文章主要給大家介紹了關(guān)于Java中泛型細(xì)節(jié)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

簡(jiǎn)介

泛型的作用就是把類(lèi)型參數(shù)化,也就是我們常說(shuō)的類(lèi)型參數(shù)

平時(shí)我們接觸的普通方法的參數(shù),比如public void fun(String s);參數(shù)的類(lèi)型是String,是固定的

現(xiàn)在泛型的作用就是再將String定義為可變的參數(shù),即定義一個(gè)類(lèi)型參數(shù)T,比如public static <T> void fun(T t);這時(shí)參數(shù)的類(lèi)型就是T的類(lèi)型,是不固定的

從上面的String和T來(lái)看,泛型有著濃濃的多態(tài)的味道,但實(shí)際上泛型跟多態(tài)還是有區(qū)別的

從本質(zhì)上來(lái)講,多態(tài)是Java中的一個(gè)特性,一個(gè)概念,泛型是真實(shí)存在的一種類(lèi)型;

正文中大部分示例都是以集合中的泛型為例來(lái)做介紹,因?yàn)橛玫谋容^多,大家都熟悉

正文

什么是類(lèi)型參數(shù)

類(lèi)型參數(shù)就是參數(shù)的類(lèi)型,它接受類(lèi)作為實(shí)際的值

白話一點(diǎn)來(lái)說(shuō),就是你可以把類(lèi)型參數(shù)看作形參,把實(shí)際傳入的類(lèi)看作實(shí)參

比如:ArrayList<E>中的類(lèi)型參數(shù)E看做形參, ArrayList<String>中的類(lèi)String看做實(shí)參

如果你學(xué)過(guò)工廠設(shè)計(jì)模式,那么就可以把這里的ArrayList<E>看做一個(gè)工廠類(lèi),然后你需要什么類(lèi)型的ArrayList,就傳入對(duì)應(yīng)的類(lèi)型參數(shù)即可

  • 比如,傳入Integer則為ArrayList<Integer>類(lèi)

  • 比如,傳入String則為ArrayList<String>類(lèi)

為啥要有泛型

主要是為了提高代碼可讀性和安全性

具體的要從泛型的演變史說(shuō)起

泛型的演變史

從廣義上來(lái)說(shuō),泛型很早就有了,只是隱式存在的;

比如List list = new ArrayList(); //等價(jià)于List<Object> list = new ArrayList<>();

但是這個(gè)時(shí)候的泛型是很脆弱的,可讀性和安全性都很差(這個(gè)時(shí)期的集合相對(duì)于數(shù)組來(lái)說(shuō),優(yōu)勢(shì)還不是很大)

首先,填充數(shù)據(jù)時(shí),沒(méi)有類(lèi)型檢查,那就有可能把Cat放到Dog集合中

其次,取出時(shí),需要類(lèi)型轉(zhuǎn)換,如果你很幸運(yùn)的把對(duì)象放錯(cuò)了集合(有可能是故意的),那么運(yùn)行時(shí)就會(huì)報(bào)錯(cuò)轉(zhuǎn)換異常(但是編譯卻可以通過(guò))

不過(guò)到了JDK1.5,出現(xiàn)了真正意義上的泛型(類(lèi)型參數(shù),用尖括號(hào)<>表示);

比如List<E>集合類(lèi),其中的E就是泛型的類(lèi)型參數(shù),因?yàn)榧现卸际谴娴脑谽lement,所以用E字母替代(類(lèi)似還有T,S,K-key,V-value);

這個(gè)時(shí)候,程序的健壯性就提高了,可讀性和安全性也都很高,看一眼就知道放進(jìn)去的是個(gè)啥東西(這個(gè)時(shí)期的集合相對(duì)于數(shù)組來(lái)說(shuō),優(yōu)勢(shì)就很明顯了

現(xiàn)在拿List<Dog> list = new ArrayList<>();來(lái)舉例說(shuō)明

首先,填充數(shù)據(jù)時(shí),編譯器自己會(huì)進(jìn)行類(lèi)型檢查,防止將Cat放入Dog中

其次,取出數(shù)據(jù)時(shí),不需要我們手動(dòng)進(jìn)行類(lèi)型轉(zhuǎn)換,編譯器自己會(huì)進(jìn)行類(lèi)型轉(zhuǎn)換

細(xì)心的你可能發(fā)現(xiàn)了,既然有了泛型,那我放進(jìn)去的是Dog,取出的不應(yīng)該也是Dog嗎?為啥編譯器還要類(lèi)型轉(zhuǎn)換呢?

這里就引出類(lèi)型擦除的概念

類(lèi)型擦除

什么是類(lèi)型擦除?

類(lèi)型擦除指的是,你在給類(lèi)型參數(shù)<T>賦值時(shí),編譯器會(huì)將實(shí)參類(lèi)型擦除為Object(這里假設(shè)沒(méi)有限定符,限定符下面會(huì)講到)

所以這里我們要明白一個(gè)東西:虛擬機(jī)中沒(méi)有泛型類(lèi)型對(duì)象的概念,在它眼里所有對(duì)象都是普通對(duì)象

比如下面的代碼

擦除前

public?class?EraseDemo<T>?{
? ?private?T?t;
? ?public?static?void?main(String[]?args) {
? ? ? ?
? }
? ?public?T?getT(){
? ? ? ?return?t;
? }
? ?public?void?setT(T?t){
? ? ? ?this.t?=?t;
? }
}

擦除后

public?class?EraseDemo?{
? ?private?Object?t;
? ?public?static?void?main(String[]?args) {
? ? ? ?
? }
? ?public?Object?getT(){
? ? ? ?return?t;
? }
? ?public?void?setT(Object?t){
? ? ? ?this.t?=?t;
? }
}

可以看到,T都變成了Object

泛型類(lèi)被擦除后的類(lèi)型,我們一般叫它原始類(lèi)型(raw type),比如EraseDemo<T>擦除后的原始類(lèi)型就是EraseDemo

相應(yīng)的,如果你有兩個(gè)數(shù)組列表,ArrayList<String>和ArrayList<Integer> ,編譯器也會(huì)把兩者都擦除為ArrayList

你可以通過(guò)代碼來(lái)測(cè)試一下

ArrayList<String>?list1?=?new?ArrayList<>();
ArrayList<Integer>?list2?=?new?ArrayList<>();
System.out.println(list1.getClass()?==?list2.getClass());// 這里會(huì)打印true

上面提到的限定符是干嘛的?

限定符就是用來(lái)限定邊界的,如果泛型有設(shè)置邊界,比如<T extends Animal>,那么擦除時(shí),會(huì)擦除到第一個(gè)邊界Animal類(lèi),而不是Object類(lèi)

下面還是以上面的代碼為例,展示下擦除前后的對(duì)比

擦除前:

public?class?EraseDemo<T?extends?Animal>?{
? ?private?T?t;
? ?public?static?void?main(String[]?args) {
? ? ? ?
? }
? ?public?T?getT(){
? ? ? ?return?t;
? }
? ?public?void?setT(T?t){
? ? ? ?this.t?=?t;
? }
}

擦除后:

public?class?EraseDemo?{
? ?private?Animal?t;
? ?public?static?void?main(String[]?args) {
? ? ? ?
? }
? ?public?Animal?getT(){
? ? ? ?return?t;
? }
? ?public?void?setT(Animal?t){
? ? ? ?this.t?=?t;
? }
}

這里的extends符號(hào)是表示繼承的意思嗎?

不是的,這里的extends只是表示前者是后者的一個(gè)子類(lèi),可以繼承也可以實(shí)現(xiàn)

之所以用extends只是因?yàn)檫@個(gè)關(guān)鍵詞已經(jīng)內(nèi)置在Java中了,且比較符合情景

如果自己再造一個(gè)關(guān)鍵詞,比如sub,可能會(huì)使得某些舊代碼產(chǎn)生問(wèn)題(比如使用sub作為變量的代碼)

為什么要擦除呢?

這其實(shí)不是想不想擦除的問(wèn)題,而是不得不擦除的問(wèn)題

因?yàn)榕f代碼是沒(méi)有泛型概念的,這里的擦除主要是為了兼容舊代碼,使得舊代碼和新代碼可以互相調(diào)用

泛型的應(yīng)用場(chǎng)景

  • 從大的方向來(lái)說(shuō):

    • 用在類(lèi)中:叫做泛型類(lèi),類(lèi)名后面緊跟<類(lèi)型參數(shù)>,比如ArrayList<E>

    • 用在方法中:叫做泛型方法,方法的返回值前面添加<類(lèi)型參數(shù)>,比如:public <T> void  fun(T obj)

是不是想到了抽象類(lèi)和抽象方法?

還是有區(qū)別的,抽象類(lèi)和抽象方法是相互關(guān)聯(lián)的,但是泛型類(lèi)和泛型方法之間沒(méi)有聯(lián)系

  • 集中到類(lèi)的方向來(lái)說(shuō):泛型多用在集合類(lèi)中,比如ArrayList<E>

如果是自定義泛型的話,推薦用泛型方法,原因有二:

  • 脫離泛型類(lèi)單獨(dú)使用,使代碼更加清晰(不用為了某個(gè)小功能而泛化整個(gè)類(lèi))

  • 泛型類(lèi)中,靜態(tài)方法無(wú)法使用類(lèi)型參數(shù);但是靜態(tài)的泛型方法可以

通配符限定

這里主要介紹<T>, <? extends T>, <? super T>的區(qū)別

  • <T>:這個(gè)是最常用的,就是普通的類(lèi)型參數(shù),在調(diào)用時(shí)傳入實(shí)際的類(lèi)來(lái)替換T即可,這個(gè)實(shí)際的類(lèi)可以是T,也可以是T的子類(lèi)

比如List<String> list = new ArrayList<>();,這里的String就是實(shí)際傳入的類(lèi),用來(lái)替換類(lèi)型參數(shù)T

  • <? extends T>:這個(gè)屬于通配符限定中的子類(lèi)型限定,即傳入實(shí)際的類(lèi)必須是T或者T子類(lèi)

乍一看,這個(gè)有點(diǎn)像<T>類(lèi)型參數(shù),都是往里放T或者T的子類(lèi);

但是區(qū)別還是挺多的,后面會(huì)列出

  • <? super T>:這個(gè)屬于通配符限定中的超類(lèi)型限定,即傳入實(shí)際的類(lèi)必須是T或者T的父類(lèi)

  • <?>:這個(gè)屬于無(wú)限定通配符,即它也不知道里面該放啥類(lèi)型,所以干脆就不讓你往里添加,只能獲?。ㄟ@一點(diǎn)類(lèi)似<? extends T>)

下面用表格列出<T>,<? extends T>, <? super T>的幾個(gè)比較明細(xì)的區(qū)別

 <T><? extends T><? super T>
類(lèi)型擦除傳入實(shí)參時(shí),實(shí)參被擦為Object,但是在get時(shí)編譯器會(huì)自動(dòng)轉(zhuǎn)為T(mén)擦到T擦到Object
引用對(duì)象不能將引用指向子類(lèi)型或者父類(lèi)型的對(duì)象,比如:List<Animal> list = new ArrayList<Cat>();//報(bào)錯(cuò)能將引用指向子類(lèi)型的對(duì)象,比如:List<? extends Animal> list = new ArrayList<Cat>();能將引用指向父類(lèi)型的對(duì)象,比如:List<? super Cat> list = new ArrayList<Animal>();
添加數(shù)據(jù)可以添加數(shù)據(jù),T或者T的子類(lèi)不能能,T或者T的子類(lèi)

下面我們用代碼來(lái)演示下

類(lèi)型擦除:

// <T>類(lèi)型,傳入實(shí)參時(shí),擦除為Object,但是get時(shí)還是實(shí)參的類(lèi)型
List<Animal>?list1?=?new?ArrayList<>();// 合法
list1.add(new?Dog());// 合法
Animal?animal?=?list1.get(0);?// 這里不需要強(qiáng)轉(zhuǎn),雖然前面?zhèn)魅雽?shí)參時(shí)被擦除為Object,但是get時(shí)編譯器內(nèi)部已經(jīng)做了強(qiáng)制類(lèi)型轉(zhuǎn)換

// <? extends T> 子類(lèi)型的通配符限定,擦除到T(整個(gè)過(guò)程不再變)
List<??extends?Animal>?list2?=?list1;// 合法
Animal?animal2?=?list2.get(0);?// 這里不需要強(qiáng)轉(zhuǎn),因?yàn)橹徊脸絋(即Animal)

// <? super T> 超類(lèi)型的通配符限定,擦除到Object
List<??super?Animal>?list3?=?list1;?// 合法
Animal?animal3?=?(Animal)list3.get(0);?// 需要手動(dòng)強(qiáng)制,因?yàn)楸徊脸絆bject

將引用指向子類(lèi)型或父類(lèi)型的對(duì)象:

// <T>類(lèi)型,不能指向子類(lèi)型或父類(lèi)型
List<Animal>?list?=?new?ArrayList<Dog>();// 報(bào)錯(cuò):需要的是List<Animal>,提供的是ArrayList<Dog>

// <? extends T> 子類(lèi)型的通配符限定,指向子類(lèi)型
List<??extends?Animal>?list2?=?new?ArrayList<Dog>();// 合法

// <? super T> 超類(lèi)型的通配符限定,指向父類(lèi)型
List<??super?Dog>?list3?=?new?ArrayList<Animal>();?// 合法

添加數(shù)據(jù)

// <T>類(lèi)型,可以添加T或者T的子類(lèi)型
List<Animal>?list1?=?new?ArrayList<>();
list.add(new?Dog());// 合法

// <? extends T> 子類(lèi)型的通配符限定,不能添加元素
List<??extends?Animal>?list2?=?new?ArrayList<Dog>();// 正確
list2.add(new?Dog());?// 報(bào)錯(cuò):不能往里添加元素

// <? super T> 超類(lèi)型的通配符限定,可以添加T或者T的子類(lèi)型
List<??super?Dog>?list3?=?new?ArrayList<Animal>();
list3.add(new?Dog());?// 合法,可以添加T類(lèi)型的元素
list3.add(new?Animal());//報(bào)錯(cuò),不能添加父類(lèi)型的元素

下面針對(duì)上面的測(cè)試結(jié)果進(jìn)行解惑

先從<T>的報(bào)錯(cuò)開(kāi)始吧

為啥<T>類(lèi)型的引用不能指向子類(lèi)型,比如 List<Animal> list = new ArrayList<Dog>();

首先說(shuō)明一點(diǎn),Animal和Dog雖然是父子關(guān)系(Dog繼承Animal),但是List<Animal> 和 List<Dog>之間是沒(méi)有任何關(guān)系的(有點(diǎn)像Java和Javascript)

他們之間的關(guān)系如下圖

之所以這樣設(shè)計(jì),主要是為了類(lèi)型安全的考慮

下面用代碼演示,假設(shè)可以將List<Animal>指向子類(lèi)List<Dog>

List<Animal>?list?=?new?ArrayList<Dog>();// 假設(shè)這里不報(bào)錯(cuò)
list.add(new?Cat());?//這里把貓放到狗里面了

第二行可以看到,很明顯,把貓放到狗里面是不對(duì)的,這就又回到了泛型真正出現(xiàn)之前的時(shí)期了(沒(méi)有泛型,集合存取數(shù)據(jù)時(shí)不安全)

那為啥<? extends T>就能指向子類(lèi)型呢?比如List<? extends Animal> list = new ArrayList<Dog>();

說(shuō)的淺一點(diǎn),原因是:這個(gè)通配符限定出現(xiàn)的目的就是為了解決上面的不能指向子類(lèi)的問(wèn)題

當(dāng)然,這個(gè)原因說(shuō)了跟沒(méi)說(shuō)一樣。下面開(kāi)始正經(jīng)點(diǎn)解釋吧

因?yàn)檫@個(gè)通配符限定不允許插入任何數(shù)據(jù),所以當(dāng)你指向子類(lèi)型時(shí),這個(gè)list就只能存放指向的那個(gè)集合里的數(shù)據(jù)了,而不能再往里添加;

自然的也就類(lèi)型安全了,只能訪問(wèn),不能添加

為什么<? extends T>不允許插入數(shù)據(jù)呢?

其實(shí)這個(gè)的原因跟上面的修改引用對(duì)象是相輔相成的,合起來(lái)就是為了保證泛型的類(lèi)型安全性

考慮下面的代碼

List<Animal>?list?=?new?ArrayList<>();
list.add(new?Cat());
list.add(new?Dog());
Dog?d?=?(Dog)?list.get(0);?// 報(bào)錯(cuò),轉(zhuǎn)換異常

可以看到,插入的子類(lèi)很混亂,導(dǎo)致提取時(shí)轉(zhuǎn)型容易出錯(cuò)(這是泛型<T>的一個(gè)弊端,當(dāng)然我們寫(xiě)的時(shí)候多用點(diǎn)心可能就不會(huì)這個(gè)問(wèn)題)

但是有了<? extends T>之后,就不一樣了

首先你可以通過(guò)修改引用的對(duì)象來(lái)使得list指向不同的Animal子類(lèi)

其次你添加數(shù)據(jù),不能直接添加,但是可以通過(guò)指向的Animal子類(lèi)對(duì)象來(lái)添加

這樣就保證了類(lèi)型的安全性

代碼如下:

// 定義一個(gè)Dog集合
List<Dog>?listDog?=?new?ArrayList<>();
listDog.add(new?Dog());

// 讓<? extends Animal>通配符限定的泛型 指向上面的Dog集合
List<??extends?Animal>?list2?=?listDog;
// 這時(shí)如果想往里添加數(shù)據(jù),只需要操作listDog即可,它可以保證類(lèi)型安全
listDog.add(new?Dog());
// 如果自己去添加,就會(huì)報(bào)錯(cuò)
list2.add(new?Dog());// 報(bào)錯(cuò)

<? extends T>一般用在形參,這樣我們需要哪個(gè)子類(lèi)型,只需要傳入對(duì)應(yīng)子類(lèi)的泛型對(duì)象就可以了,從而實(shí)現(xiàn)泛型中的多態(tài)

<? super T>為啥可以插入呢?

兩個(gè)原因

  • 它只能插入T或者T的子類(lèi)

  • 它的下限是T

也就是說(shuō)你隨便插入,我已經(jīng)限制了你插入的類(lèi)型為T(mén)或者T的子類(lèi)

那么我在查詢(xún)時(shí),就可以放心的轉(zhuǎn)為T(mén)或者T的父類(lèi)

代碼如下:

List<??super?Dog>?listDog?=?new?ArrayList<>();
listDog.add(new?Dog());
listDog.add(new?Cat());?// 報(bào)錯(cuò)
listDog.add(new?Animal());?// 報(bào)錯(cuò)
Dog?dog?=?(Dog)?listDog.get(0);?// 內(nèi)部被擦除為Object,所以要手動(dòng)強(qiáng)轉(zhuǎn)

為啥<T>獲取時(shí),編譯器會(huì)自動(dòng)強(qiáng)轉(zhuǎn)轉(zhuǎn)換,到了這里<? super T>,就要手動(dòng)轉(zhuǎn)換了呢?

這個(gè)可能是因?yàn)榫幾g器也不確定你的要返回的T的父類(lèi)是什么類(lèi)型,所以干脆留給你自己來(lái)處理了

但是如果你把這個(gè)listDog指向一個(gè)父類(lèi)的泛型對(duì)象,然后又在父類(lèi)的泛型對(duì)象中,插入其他類(lèi)型,那可就亂了(又回到<T>的問(wèn)題了,要自己多注意)

比如:

List<Animal>?list?=?new?ArrayList<>();
list.add(new?Cat());?// 加了Cat
// 指向Animal
List<??super?Dog>?listDog?=?list;
listDog.add(new?Dog());
list.add(new?Cat());?// 報(bào)錯(cuò)
list.add(new?Animal());?// 報(bào)錯(cuò)

Dog?dog?=?(Dog)?listDog.get(0);?//報(bào)錯(cuò):轉(zhuǎn)換異常Cat-》Dog

所以建議<? super T>在添加數(shù)據(jù)的時(shí)候,盡量集中在一個(gè)地方,不要多個(gè)地方添加,像上面的,要么都在<? super Dog>里添加數(shù)據(jù),要么都在<Animal>中添加

動(dòng)態(tài)類(lèi)型安全檢查

這個(gè)主要是為了跟舊代碼兼容,對(duì)舊代碼進(jìn)行的一種類(lèi)型安全檢查,防止將Cat插入Dog集合中這種錯(cuò)誤

這種檢查是發(fā)生在編譯階段,這樣就可以提早發(fā)現(xiàn)問(wèn)題

對(duì)應(yīng)的類(lèi)為Collections工具類(lèi),方法如下圖

代碼如下

// 動(dòng)態(tài)類(lèi)型安全檢查,在與舊代碼兼容時(shí),防止將Dog放到Cat集合中類(lèi)似的問(wèn)題

// === 檢查之前 ===
List?list?=?new?ArrayList<Integer>();
// 添加不報(bào)錯(cuò)
list.add("a");
list.add(1);
// 只有用的時(shí)候,才會(huì)報(bào)錯(cuò)
Integer?i?=?(Integer)?list.get(0);?// 這里運(yùn)行時(shí)報(bào)錯(cuò)

// === 檢查之后 ===
List?list2?=?Collections.checkedList(new?ArrayList<>(),?Integer.class);
// 插入時(shí)就會(huì)報(bào)錯(cuò)
list2.add("a");?// 這里編譯時(shí)就報(bào)錯(cuò),提前發(fā)現(xiàn)錯(cuò)誤
list2.add(1);

總結(jié)

泛型的作用:

  • 提高類(lèi)型安全性:預(yù)防各種類(lèi)型轉(zhuǎn)換問(wèn)題

  • 增加程序可讀性:所見(jiàn)即所得,看得到放進(jìn)去的是啥,也知道會(huì)取出啥

  • 提高代碼重用性:多種同類(lèi)型的數(shù)據(jù)(比如Animal下的Dog,Cat)可以集合到一處來(lái)處理,從而調(diào)高代碼重用性

類(lèi)型擦除:

泛型T在傳入實(shí)參時(shí),實(shí)參的類(lèi)型會(huì)被擦除為限定類(lèi)型(即<? extends T>中的T),如果沒(méi)有限定類(lèi)型,則默認(rèn)為Object

通配符限定:

  • <? extends T>:子類(lèi)型的通配符限定,以查詢(xún)?yōu)橹?/strong>,比如消費(fèi)者集合場(chǎng)景

  • <? super T>:超類(lèi)型的通配符限定,以添加為主,比如生產(chǎn)者集合場(chǎng)景

 到此這篇關(guān)于Java中泛型學(xué)習(xí)之細(xì)節(jié)篇的文章就介紹到這了,更多相關(guān)Java中泛型細(xì)節(jié)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Mybatis的xml中使用if/else標(biāo)簽的具體使用

    Mybatis的xml中使用if/else標(biāo)簽的具體使用

    本文主要介紹了Mybatis的xml中使用if/else標(biāo)簽的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • Java實(shí)現(xiàn)經(jīng)典大富翁游戲的示例詳解

    Java實(shí)現(xiàn)經(jīng)典大富翁游戲的示例詳解

    大富翁,又名地產(chǎn)大亨。是一種多人策略圖版游戲。參與者分得游戲金錢(qián),憑運(yùn)氣(擲骰子)及交易策略,買(mǎi)地、建樓以賺取租金。本文將通過(guò)Java實(shí)現(xiàn)這一經(jīng)典游戲,感興趣的可以跟隨小編一起學(xué)習(xí)一下
    2022-02-02
  • Java抽象類(lèi)概念與用法實(shí)例分析

    Java抽象類(lèi)概念與用法實(shí)例分析

    這篇文章主要介紹了Java抽象類(lèi)概念與用法,結(jié)合實(shí)例形式分析了java抽象類(lèi)的概念、方法、特點(diǎn)及使用方法,需要的朋友可以參考下
    2018-02-02
  • Java使用遞歸回溯完美解決八皇后的問(wèn)題

    Java使用遞歸回溯完美解決八皇后的問(wèn)題

    這篇文章主要介紹了Java基于循環(huán)遞歸回溯實(shí)現(xiàn)八皇后問(wèn)題算法,結(jié)合具體實(shí)例形式分析了java的遍歷、遞歸、回溯等算法實(shí)現(xiàn)八皇后問(wèn)題的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下
    2021-11-11
  • Protobuf的簡(jiǎn)要介紹及使用詳解

    Protobuf的簡(jiǎn)要介紹及使用詳解

    這篇文章主要介紹了Protobuf的簡(jiǎn)要介紹及使用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • MyBatis-Plus實(shí)現(xiàn)邏輯刪除功能解析

    MyBatis-Plus實(shí)現(xiàn)邏輯刪除功能解析

    這篇文章主要介紹了MyBatis-Plus實(shí)現(xiàn)邏輯刪除功能解析,有時(shí)候并不需要真正的刪除數(shù)據(jù),而是想邏輯刪除,方便數(shù)據(jù)恢復(fù),MyBatis-Plus可以很方便的實(shí)現(xiàn)邏輯刪除的功能,需要的朋友可以參考下
    2023-11-11
  • SpringBoot中間件之封裝統(tǒng)一白名單配置

    SpringBoot中間件之封裝統(tǒng)一白名單配置

    這篇文章主要介紹了SpringBoot中間件封裝統(tǒng)一白名單配置,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • BeanUtils.copyProperties()拷貝id屬性失敗的原因及解決

    BeanUtils.copyProperties()拷貝id屬性失敗的原因及解決

    這篇文章主要介紹了BeanUtils.copyProperties()拷貝id屬性失敗的原因及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • SpringBoot圖文并茂講解Lombok庫(kù)的安裝與使用

    SpringBoot圖文并茂講解Lombok庫(kù)的安裝與使用

    Lombok想要解決了的是在我們實(shí)體Bean中大量的Getter/Setter方法,以及toString, hashCode等可能不會(huì)用到,但是某些時(shí)候仍然需要復(fù)寫(xiě),以期方便使用的方法;在使用Lombok之后,將由其來(lái)自動(dòng)幫你實(shí)現(xiàn)代碼生成
    2022-06-06
  • Java使用@Validated注解進(jìn)行參數(shù)驗(yàn)證的方法

    Java使用@Validated注解進(jìn)行參數(shù)驗(yàn)證的方法

    這篇文章主要介紹了Java使用@Validated注解進(jìn)行參數(shù)驗(yàn)證的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08

最新評(píng)論