一文詳解Java中的包裝類和泛型
前言
在Java中,由于基本類型不是繼承?Object,為了在泛型中可以?持基本類型,Java給每個基本類型都對應(yīng)了?個包裝類型,有些情況下只有接收泛型才可以完成其功能
包裝類
基本數(shù)據(jù)類型 | 包裝類 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
這里的除了int 和char 類型的包裝類是Integer和Character 其他的都是其首字母大寫
裝箱和拆箱
public class Test { public static void main(String[] args) { int a = 10; //裝箱操作 將a的值放入包裝類型中 Integer a1 = Integer.valueOf(a); Integer a2 = new Integer(a); //拆箱,將其包裝類型的數(shù)據(jù)放入基本數(shù)據(jù)類型中 int i = a1.intValue(); int j = a2.intValue(); System.out.println(a1); System.out.println(a2); System.out.println(i); System.out.println(j); } }
運(yùn)行結(jié)果如下
上面我們在裝箱和拆箱的時候,都要利用其官方的方法,這樣導(dǎo)致代碼量增多
自動裝箱和拆箱
public class Test { public static void main(String[] args) { int a = 10; Integer a1 = (Integer) a;//強(qiáng)制類型轉(zhuǎn)換 Integer a2 = a;//自動類型轉(zhuǎn)換 int a3 = a1;//自動類型轉(zhuǎn)換 int a4 = (int) a2;//強(qiáng)制類型轉(zhuǎn)換 System.out.println(a1); System.out.println(a2); System.out.println(a3); System.out.println(a4); } }
這里可以強(qiáng)制類型轉(zhuǎn)換,也可以自動類型轉(zhuǎn)換,Java是提供了這個機(jī)制
運(yùn)行結(jié)果如下
基本類型和包裝類型其實(shí)并不完全相同
public class Test { public static void main(String[] args) { Integer a1 = 10; Integer a2 = 10; Integer a3 = 128; Integer a4 = 128; System.out.println(a1==a2); System.out.println(a3==a4); } }
運(yùn)行結(jié)果如下
這里是自動調(diào)用其Integer.valueOf方法
這里如果換成普通數(shù)據(jù)類型這里就相同了,就輸出兩個true,但是換成包裝類型,這里的結(jié)果就變了,為什么呢,這就要看看其包裝類型的存儲了
因?yàn)檫@里的傳入值如果為[-128,127]放其給定好的數(shù)組中,反之則new一個新對象,所以這里超過其這個范圍兩個地址不相同了,所以這里的127返回true,128返回false
泛型
泛型的概念
以前在寫方法的時候,都是使用的基本類型,這樣此方法只可以用于這一種類型,那可不可以創(chuàng)建一個方法可以讓多種數(shù)據(jù)類型都可以使用呢,這就引入了泛型,就是其可以使用多種類型
我們可以先自己定義一個數(shù)組可以存放多種類型的數(shù)據(jù),里面有存放和獲取一個下標(biāo)數(shù)值
class MyArray{ public Object[] array = new Object[10]; public Object getval(int index){ return array[index]; } public void setval(int index,int val){ this.array[index] = val; } } public class Test { public static void main(String[] args) { MyArray myArray = new MyArray(); myArray.setval(0,1); System.out.println(myArray.getval(0)); } }
運(yùn)行結(jié)果如下
但是要注意創(chuàng)建一個對象以后,添加了一種類型的數(shù)據(jù),就不可以在添加另外一種數(shù)據(jù)了
一個數(shù)組中的元素類型要一致
就像上面已經(jīng)添加了int類型就說明這里是int類型數(shù)組,因此不可以在添加其他數(shù)據(jù)類型,這里如果在添加String類型就會出錯
泛型的使用
定義一個泛型類
class 泛型類名稱<類型形參列表> {
} // 這?可以使?類型參數(shù)
也可以放多種類型
class ClassName<T1, T2, …, Tn> {
}
這個泛型方法的使用
泛型類<類型實(shí)參> 變量名= new 泛型類<類型實(shí)參>(構(gòu)造?法實(shí)參);
//定義一個泛型類引用,并實(shí)例化一個對象
例如
ArrayList< Integer > list = new ArrayList<>();//實(shí)例化一個Integer數(shù)據(jù)類型的列表
這里在實(shí)例化的時候<>內(nèi)不用在寫是什么類型,編譯器會從前面推導(dǎo)出來
有了這個上面的代碼就可以改為
class MyArray<T>{ public Object[] array = new Object[10]; public T getval(int index){ return (T)array[index]; } public void setval(int index,int val){ this.array[index] = val; } } public class Test { public static void main(String[] args) { //這里指定了是Integer包裝類型的數(shù)組 //就不可以存儲其以外的數(shù)據(jù)了 MyArray<Integer> myArray = new MyArray(); myArray.setval(0,1); //myArray.setval(1,"124"); System.out.println(myArray.getval(0)); } }
這里在創(chuàng)建對象的時候就確定了是什么數(shù)據(jù)類型的數(shù)組
并且這里的數(shù)組數(shù)據(jù)類型只可以是包裝類型
1.如果寫成普通數(shù)據(jù)類型就會報錯,這里需要的是包裝類型
2.確定了數(shù)據(jù)類型就不可以存放其他數(shù)據(jù)類型了
交換的泛型方法
public class Test { public static void main(String[] args) { Integer[] arr ={1,2,3}; swap(arr,1,2); } //這里靜態(tài)泛型方法前面要說明是什么類型 public static <T> void swap(T[] array,int i,int j){ T tem = array[i]; array[i] = array[j]; array[j] = tem; } }
這里前面的T是不可以省略的,用于確定其是什么類型
1.類名后的 <T> 代表占位符,表?當(dāng)前類是?個泛型類 E表?Element, K表?Key , V表?Value ,N表?Number ,T表?Type 2.創(chuàng)建對象的時候就確認(rèn)其數(shù)組數(shù)據(jù)類型,并且只可以是包裝類型 3.確認(rèn)數(shù)據(jù)類型就不可以在其數(shù)組放入其他數(shù)據(jù)類型的數(shù)據(jù)了
泛型的上界
在定義泛型類的時候有時候我們要對其傳入數(shù)據(jù)類型進(jìn)行限制,于是就引出了泛型的上界
class 泛型類名稱<類型形參 extends 類型邊界> {
…
}
例如上面
public class MyArray< E extends Number> {
…
}
//這里表示上界是Number
例如
class MyArray<T extends Number>{ public Object[] array = new Object[10]; public T getval(int index){ return (T)array[index]; } public void setval(int index,int val){ this.array[index] = val; } }
例如上面這個類就是上界是Number
也就是這里是要是int double float類型等等數(shù)字類型
public class Test { public static void main(String[] args) { MyArray<Integer> myArray = new MyArray<>(); MyArray<Double> myArray1 = new MyArray<>(); MyArray<Float> myArray2 = new MyArray<>(); } }
這里要求的上界是Number數(shù)字,如果不是數(shù)字類型的包裝類型就會報錯,例如下面?zhèn)魅胍脭?shù)據(jù)類型就會報錯
通配符
通配符概念
?也可以用于泛型的使用,也就是通配符
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("hello world"); fun(message); } public static void fun(Message<String> message){ System.out.println(message.getMessage()); } }
運(yùn)行結(jié)果如下
我們發(fā)現(xiàn)上面的fun函數(shù)并不是泛型,只可以打印和接收String類型,如果是其他的類型就會報錯,這明顯不符合我們的需求,我們要其可以接收和打印多種類型
如果這里傳入Integer類型就會報錯
因此這時候我們就可以使用通配符?
public class Test { public static void main(String[] args) { Message<String> message = new Message<>(); message.setMessage("hello world"); fun(message); Message<Integer> message1 = new Message<>(); message1.setMessage(1111); fun(message1); } //傳入什么類型,這個就是什么類型 public static void fun(Message<?> message){ System.out.println(message.getMessage()); } }
運(yùn)行結(jié)果如下
其實(shí)這里我們使用上面的泛型也可以
public static<T> void fun(Message<T> message){ System.out.println(message.getMessage()); }
通配符上界
<?extend 上界>
定義了一個Food類
class Food{ } class Fruit extends Food{ } class Banana extends Fruit{ } class Apple extends Fruit{ } class Plate<T>{ private T plate; public T getPlate() { return plate; } public void setPlate(T plate) { this.plate = plate; } } public class Test { public static void main(String[] args) { //這里的類型要為Fruit或者其子類 Plate<Apple> plate1 = new Plate<>(); plate1.setPlate(new Apple()); fun(plate1); Plate<Banana> plate2 = new Plate<>(); plate2.setPlate(new Banana()); fun(plate2); // fun(new Food());//這個超越了上界 } //fun用于打印 //這里表示只可以傳入Fruit及其子類 public static void fun(Plate<? extends Fruit> plate){ // plate.setPlate(new Apple()); // plate.setPlate(new Banana()); //在這里不可以添加元素,因?yàn)檫@里的plate不知道是那個的子類,報錯 System.out.println(plate.getPlate()); } }
運(yùn)行結(jié)果如下
這里的fun函數(shù)參數(shù)的上界為Fruit,所以其只可以接收,F(xiàn)ruit及其子類
如果傳入Food,是Fruit的父類肯定報錯,超越了上界
并且不可以在其fun函數(shù)里,來進(jìn)行添加元素
因?yàn)檫@里的plate是那個子類我們并不知道,不知道添加什么類型的元素
通配符下界
<? super 下界>
還是利用上面的
class Food{ } class Fruit extends Food{ } class Banana extends Fruit{ } class Apple extends Fruit{ } class Plate<T>{ private T plate; public T getPlate() { return plate; } public void setPlate(T plate) { this.plate = plate; } } public class Test { public static void main(String[] args) { Plate<Fruit> plate = new Plate<>(); plate.setPlate(new Fruit()); fun(plate); Plate<Food> plate1 = new Plate<>(); plate1.setPlate(new Food()); fun(plate1); // Plate<Apple> plate2 = new Plate<>(); // plate2.setPlate(new Apple()); // fun(plate2);//下界為Fruit,只可以傳入Fruit及其子類 } public static void fun(Plate<? super Fruit> plate){ System.out.println(plate.getPlate()); } }
運(yùn)行結(jié)果如下
這里下界為Fruit,只可以傳入Fruit及其父類
不可以傳入其子類
由于這里fun函數(shù)接收的下界為Fruit,所以其是可以在里面添加其Fruit子類對象
public static void fun(Plate<? super Fruit> plate){ plate.setPlate(new Apple()); plate.setPlate(new Banana()); plate.setPlate(new Fruit()); System.out.println(plate.getPlate()); }
雖然可以添加,但是不可以接收,因?yàn)椴恢朗怯媚囊粋€父類來接收,F(xiàn)ruit可能有很多父類
到這里就結(jié)束了。
以上就是一文詳解Java中的包裝類和泛型的詳細(xì)內(nèi)容,更多關(guān)于Java包裝類和泛型的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
struts2中通過json傳值解決亂碼問題的實(shí)現(xiàn)方法
這篇文章主要介紹了struts2中通過json傳值解決亂碼問題的實(shí)現(xiàn)方法,涉及js編碼及java解碼的相關(guān)操作技巧,需要的朋友可以參考下2016-06-06解決Eclipse add external jars運(yùn)行出現(xiàn)java.lang.NoClassDefFoundErro
本篇文章對Eclipse add external jars導(dǎo)致運(yùn)行出現(xiàn)java.lang.NoClassDefFoundError的解決方法進(jìn)行了詳細(xì)的分析介紹。需要的朋友參考下2013-05-05Java語言通過三種方法實(shí)現(xiàn)隊(duì)列的示例代碼
這篇文章主要介紹了Java語言通過三種方法來實(shí)現(xiàn)隊(duì)列的實(shí)例代碼,數(shù)組模擬隊(duì)列,通過對定義的了解,發(fā)現(xiàn)隊(duì)列很像我們的數(shù)組,下面我們通過實(shí)踐給大家詳細(xì)介紹,需要的朋友可以參考下2022-02-02詳解Spring中Bean后置處理器(BeanPostProcessor)的使用
BeanPostProcessor 接口也被稱為Bean后置處理器,通過該接口可以自定義調(diào)用初始化前后執(zhí)行的操作方法。本文將詳細(xì)講講它的使用,需要的可以參考一下2022-06-06Java語言實(shí)現(xiàn)簡單FTP軟件 FTP軟件本地窗口實(shí)現(xiàn)(5)
這篇文章主要為大家詳細(xì)介紹了Java語言實(shí)現(xiàn)簡單FTP軟件,F(xiàn)TP軟件本地窗口的實(shí)現(xiàn)方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-03-03