Java重溫學習筆記,關於泛型
阿新 • • 發佈:2021-06-19
Java泛型(generics)是 JDK 5 中引入的一個新特性, 泛型提供了編譯時型別安全檢測機制,該機制允許程式設計師在編譯時檢測到非法的型別。
泛型的本質是引數化型別,也就是說所操作的資料型別被指定為一個引數。
一、先看下面的例子:
import java.util.*; public class MyDemo { public static void main(String[] args) { List arrayList = new ArrayList(); arrayList.add("hello"); arrayList.add(1688); for(int i = 0; i< arrayList.size();i++){ String item = (String)arrayList.get(i); System.out.println("當前值:" + item); } } }
上面程式碼編譯可以通過,但執行時報錯:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at MyDemo.main(MyDemo.java:10)
二、對程式碼作如下修改,則會在編譯階段就會出錯
import java.util.*; public class MyDemo { public static void main(String[] args) { List<String> arrayList = new ArrayList<String>(); arrayList.add("hello"); arrayList.add(1688); for(int i = 0; i< arrayList.size();i++){ String item= (String)arrayList.get(i); System.out.println("當前值:" + item); } } }
%:\Work\helloworld\MyDemo.java:7: 錯誤: 對於add(int), 找不到合適的方法
arrayList.add(1688);
^
三、泛型有三種使用方式,分別為:泛型類、泛型介面、泛型方法
1. 泛型類示範程式碼
//此處T可以隨便寫為任意標識,常見的如T、E、K、V等形式的引數常用於表示泛型 //在例項化泛型類時,必須指定T的具體型別 class Generic<T>{ //key這個成員變數的型別為T,T的型別由外部指定 private T key; public Generic(T key) { //泛型構造方法形參key的型別也為T,T的型別由外部指定 this.key = key; } public T getKey(){ //泛型方法getKey的返回值型別為T,T的型別由外部指定 return key; } } public class MyDemo { public static void main(String[] args) { //泛型的型別引數只能是類型別(包括自定義類),不能是簡單型別 //傳入的實參型別需與泛型的型別引數型別相同,即為Integer. Generic<Integer> genericInteger = new Generic<Integer>(123456); //傳入的實參型別需與泛型的型別引數型別相同,即為String. Generic<String> genericString = new Generic<String>("key_vlaue"); System.out.println(genericInteger.getKey()); System.out.println(genericString.getKey()); } }
2. 泛型介面示範程式碼
import java.util.*; interface Generator<T> { public T next(); } class FruitGenerator implements Generator<String> { private String[] fruits = new String[]{"Apple", "Banana", "Other"}; @Override public String next() { Random rand = new Random(); return fruits[rand.nextInt(3)]; } } class CarGenerator implements Generator<Boolean> { private Boolean[] myCar = new Boolean[]{true, false, true, false}; @Override public Boolean next() { Random rand = new Random(); return myCar[rand.nextInt(3)]; } } public class MyDemo { public static void main(String[] args) { FruitGenerator fruit = new FruitGenerator(); System.out.println(fruit.next()); System.out.println(fruit.next()); System.out.println(fruit.next()); CarGenerator car = new CarGenerator(); System.out.println(car.next()); System.out.println(car.next()); System.out.println(car.next()); } }
3.類中的泛型方法
public class GenericFruit { static class Fruit{ @Override public String toString() { return "fruit"; } } static class Apple extends Fruit{ @Override public String toString() { return "apple"; } } static class Person{ @Override public String toString() { return "Person"; } } static class GenerateTest<T>{ public void show_1(T t){ System.out.println(t.toString()); } // 在泛型類中聲明瞭一個泛型方法,使用泛型T,注意這個T是一種全新的型別,可以與泛型類中宣告的T不是同一種類型。 public <T> void show_2(T t){ System.out.println(t.toString()); } } public static void main(String[] args) { Apple apple = new Apple(); Person person = new Person(); GenerateTest<Fruit> generateTest = new GenerateTest<Fruit>(); //apple是Fruit的子類,所以這裡編譯正常 generateTest.show_1(apple); //下面一行程式碼編譯器會報錯,因為泛型型別實參指定的是Fruit,而傳入的實參類是Person //generateTest.show_1(person); // 下面程式碼可以正常執行 generateTest.show_2(apple); generateTest.show_2(person); } }
文章參考:
https://blog.csdn.net/s10461/article/details/53941091