建網(wǎng)站程序怎么寫中小型企業(yè)網(wǎng)站設(shè)計(jì)與開發(fā)
文章目錄
- 📕1. 包裝類
- ??1.1 基本數(shù)據(jù)類型和對(duì)應(yīng)的包裝類
- ??1.2 裝箱和拆箱
- ??1.3 自動(dòng)裝箱和自動(dòng)拆箱
- 📕2. 泛型
- ??2.1 泛型的語法
- ??2.2 泛型類的使用
- ??2.3 裸類型(Raw Type)
- ??2.4 擦除機(jī)制
- ??2.5 泛型的上界
- ??2.6 泛型方法
- ??2.7 通配符
📕1. 包裝類
在JAVA中,共有8種基本類型,分別是byte,short,long,int,double,float,char,boolean.但由于JAVA是一門純面向?qū)ο蟮恼Z言,而且8種基本并非繼承于Object類,為了在泛型代碼中可以?持基本類型,于是JAVA提供了包裝類。
??1.1 基本數(shù)據(jù)類型和對(duì)應(yīng)的包裝類
除了 Integer 和 Character, 其余基本類型的包裝類都是?字??寫。
??1.2 裝箱和拆箱
- 裝箱:基本數(shù)據(jù)類型轉(zhuǎn)換成包裝類
int i = 10;
Integer ij = new Integer(i);
//裝箱
- 拆箱:包裝類轉(zhuǎn)換成基本數(shù)據(jù)類型
int i = 10;
Integer ij = new Integer(i);
int j = ii.intValue();
//拆箱
💡注意:現(xiàn)在都使用自動(dòng)拆箱和自動(dòng)裝箱!!!
??1.3 自動(dòng)裝箱和自動(dòng)拆箱
為了減少開發(fā)者的負(fù)擔(dān),java 提供了?動(dòng)機(jī)制。
- 自動(dòng)裝箱
int i = 10;Integer j = i;//自動(dòng)裝箱
- 自動(dòng)拆箱
Integer j = 10;
int a = j;//自動(dòng)拆箱
?提問:下述代碼分別輸出什么,為什么?
public class Test {public static void main(String[] args) {Integer a = 127;Integer b = 127;Integer c = 128;Integer d = 128;Integer e = -129;Integer f = -129;System.out.println(a == b);//trueSystem.out.println(c == d);//falseSystem.out.println(e == f);//false}
}
💡注意:a和b是應(yīng)用類型,==比較的是身份,比較值要重寫equals方法進(jìn)行比較。
答:[-128,127]這個(gè)范圍數(shù)字比較是會(huì)出現(xiàn)true,其他數(shù)字比較則會(huì)出現(xiàn)false。原因是Integer中常用的數(shù)字被放到了常量池里,常用數(shù)字的范圍是[-128,127].
📕2. 泛型
我們以前學(xué)過的數(shù)組,只能存放指定類型的元素,但是因?yàn)樗蓄惖母割惗际荗bject類,所以數(shù)組類型是否可以創(chuàng)建成Object呢?
class MyArray {private Object[] array = new Object[10];public Object getPos(int pos) {return this.array[pos];}public void setVal(int pos,Object val) {this.array[pos] = val;}
}
public class Test {public static void main(String[] args) {MyArray myArray = new MyArray();myArray.setVal(0,10);myArray.setVal(1,"hello");//字符串也可以存放String ret = myArray.getPos(1);//編譯報(bào)錯(cuò)System.out.println(ret);}
}
//1號(hào)下標(biāo)本?就是字符串,但是確編譯報(bào)錯(cuò)。必須進(jìn)?強(qiáng)制類型轉(zhuǎn)換
雖然在這種情況下,當(dāng)前數(shù)組任何數(shù)據(jù)都可以存放,但是,更多情況下,我們還是希望 它只能夠持有
?種數(shù)據(jù)類型。?不是同時(shí)持有這么多類型。所以,泛型的主要目的:就是指定當(dāng)前的容器,要持有
什么類型的對(duì)象,讓編譯器去做檢查。 此時(shí),就需要把類型,作為參數(shù)傳遞。需要什么類型,就傳?
什么類型。
??2.1 泛型的語法
基礎(chǔ)寫法:
class 泛型類名稱<類型形參列表> {// 這?可以使?類型參數(shù)
}
其他寫法:
class 泛型類名稱<類型形參列表> extends 繼承類/* 這?可以使?類型參數(shù) */ {// 這?可以使?類型參數(shù)
}
上述代碼進(jìn)?改寫如下:
class MyArray<T> {public Object[] array = new Object[10];public T getPos(int pos) {return (T)this.array[pos];}public void setVal(int pos,T val) {this.array[pos] = val;}
}
public class TestDemo {public static void main(String[] args) {MyArray<Integer> myArray = new MyArray<>();//1myArray.setVal(0,10);myArray.setVal(1,12);int ret = myArray.getPos(1);//2System.out.println(ret);myArray.setVal(2,"小朱小朱");//3 編譯報(bào)錯(cuò)!!!}
}
1. 注釋1處,類型后加? 指定當(dāng)前類型
2. 注釋2處,不需要進(jìn)行強(qiáng)制類型轉(zhuǎn)換
3. 注釋3處,代碼編譯報(bào)錯(cuò),此時(shí)因?yàn)樵谧⑨?處指定類當(dāng)前的類型,此時(shí)編譯器會(huì)在存放元素的時(shí)候幫助我們進(jìn)行類型檢查。
代碼解釋:
- 類名后的 < T >代表占位符,表?當(dāng)前類是?個(gè)泛型類
- 【規(guī)范】類型形參?般使??個(gè)?寫字?表示,常?的名稱有:
? E 表示Element
? K 表示 Key
? V 表示 Value
? N 表示 Number
? T 表示 Type
? S, U, V 等等 - 第?、第三、第四個(gè)類型
??2.2 泛型類的使用
泛型類<類型實(shí)參> 變量名; // 定義?個(gè)泛型類引?
new 泛型類<類型實(shí)參>(構(gòu)造?法實(shí)參); // 實(shí)例化?個(gè)泛型類對(duì)象MyArray<Integer> list = new MyArray<Integer>();
注意:泛型只能接受類,所有的基本數(shù)據(jù)類型必須使用包裝類!
??2.3 裸類型(Raw Type)
裸類型是?個(gè)泛型類但沒有帶著類型實(shí)參,例如 MyArrayList 就是?個(gè)裸類型
MyArray list = new MyArray();
??2.4 擦除機(jī)制
在編譯時(shí),Java 編譯器會(huì)將泛型類型信息從代碼中移除,這個(gè)過程就叫做類型擦除。擦除后,泛型類型會(huì)被替換為其邊界類型(通常是 Object)或者指定的類型。同時(shí)也會(huì)在必要的地方插?類型轉(zhuǎn)換以保持類型安全。
擦除前:
class MyArray<T> {public Object[] array = new Object[10];public T getPos(int pos) {return (T)this.array[pos];}public void setVal(int pos,T val) {this.array[pos] = val;}
}
擦除后:
class MyArray {public Object[] array = new Object[10];public Object getPos(int pos) {return this.array[pos];}public void setVal(int pos, Object val) {this.array[pos] = val;}
}
??2.5 泛型的上界
在定義泛型類時(shí),有時(shí)需要對(duì)傳?的類型變量做?定的約束,可以通過類型邊界來約束。
語法:
class 泛型類名稱<類型形參 extends 類型邊界> {
...
}public class MyArray<E extends Number> {
...
}
//只接受 Number 的?類型作為 E 的類型實(shí)參
??2.6 泛型方法
語法:
?法限定符 <類型形參列表> 返回值類型 ?法名稱(形參列表){...}
示例:
public class Util {//靜態(tài)的泛型?法 需要在static后?<>聲明泛型類型參數(shù)public static <E> void swap(E[] array, int i, int j) {E t = array[i];array[i] = array[j];array[j] = t;}
}
??2.7 通配符
?用于在泛型的使?,即為通配符
請(qǐng)觀察下述代碼:
class Message<T> {private T message ;public T getMessage() {return message;}public void setMessage(T message) {this.message = message;}
}
public class Test {public static void main(String[] args) {Message<String> message = new Message<>() ;message.setMessage("歡迎來到小朱的CSDN");fun(message);}public static void fun(Message<String> temp){System.out.println(temp.getMessage());}
}
以上程序會(huì)帶來新的問題,如果現(xiàn)在泛型的類型設(shè)置的不是String,?是Integer.
public class TestDemo {public static void main(String[] args) {Message<Integer> message = new Message() ;message.setMessage(99);fun(message); // 出現(xiàn)錯(cuò)誤,只能接收String}public static void fun(Message<String> temp){System.out.println(temp.getMessage());}
}
我們需要的解決方案:可以接收所有的泛型類型,但是又不能夠讓用戶隨意修改。這種情況就需要使
?通配符"?"來處理
public class TestDemo {public static void main(String[] args) {Message<Integer> message = new Message() ;message.setMessage(55);fun(message);}// 此時(shí)使?通配符"?"描述的是它可以接收任意類型public static void fun(Message<?> temp){System.out.println(temp.getMessage());}
}
在"?"的基礎(chǔ)上又產(chǎn)生了兩個(gè)子通配符:
通配符上界:
<? extends 上界>
<? extends Number>//可以傳?的實(shí)參類型是Number或者Number的?類
通配符下界:
<? super 下界>
<? super Integer>//代表 可以傳?的實(shí)參的類型是Integer或者Integer的?類類型