泛型
public static void main(String[] args) {
//List list = new ArrayList();
//指定能夠存放的資料型別,統一型別防止出現 型別轉換異常
List<String> list = new ArrayList();
list.add(1);
list.add("hello");
list.add(new Object());
for (Object obj:list) {
System.out.println((String)obj); //java.lang.ClassCastException
}
}
本質:引數化型別
泛型的擦除
泛型只在編譯階段有效,編譯之後JVM會採取去泛型化的措施.
泛型在執行階段是沒有效果
public static void main(String[] args) throws Exception {
List<String> list = new ArrayList();
list.add("1");
list.add("hello");
list.add("2");
for (Object obj:list) {
System.out.println((String)obj);
}
//反射賦值
Class<? extends List> aClass = list.getClass();
Method method = aClass.getDeclaredMethod("add", Object.class);
method.invoke(list,new Object());
System.out.println(list);//沒有任何問題
}
一、泛型萬用字元介紹
1、無邊界萬用字元
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
list1.add("gupao");
list1.add("bobo");
list1.add("mic");
loop(list1);
}
/**
* < ? > 通用的型別可以是任意型別
*/
public static void loop(List<?> list){
for (int i = 0; i < list.size() ; i++) {
System.out.println(list.get(i));
}
}
2、上邊界萬用字元
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
list1.add("gupao");
list1.add("bobo");
list1.add("mic");
// loop(list1);
List<Number> list2 = new ArrayList<>();
list2.add(1);
list2.add(2);
list2.add(3);
}
/**
* < ? extends Number >
* 通用的型別必須是Number及其子類
* @param list
*/
public static void loop(List<? extends Number> list){
for (int i = 0; i < list.size() ; i++) {
System.out.println(list.get(i));
}
}
3、下邊界萬用字元
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
list1.add("gupao");
list1.add("bobo");
list1.add("mic");
loop(list1);
List<Number> list2 = new ArrayList<>();
list2.add(1);
list2.add(2);
list2.add(3);
loop(list2);
}
/**
* < ? super Number >
* 通用型別必須是Number 到Object型別的物件
* @param list
*/
public static void loop(List<? super Number> list){
for (int i = 0; i < list.size() ; i++) {
System.out.println(list.get(i));
}
}
二、泛型的具體使用
規則: 必須先宣告再使用
1、泛型的宣告是通過"<>"實現
2、約定泛型可以使用單個大寫字母來表示 K E T V 等
/**
* 泛型沒有宣告就直接使用了
* @param t
* @return
*/
public <T> T func(T t){
return null;
}
1、泛型類
public class Fun <T>{
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
public Fun(T t) {
this.t = t;
}
}
//PersonBean
public class PersonBean {
private int id;
private String name;
private String password;
//get/set
}
//測試
public static void main(String[] args) {
PersonBean bean = new PersonBean();
bean.setId(1);
bean.setName("Andy");
bean.setPassword("12345");
Fun<PersonBean> pn = new Fun(bean); //PersonBean
Fun<String> s = new Fun("hello"); //String
}
增加了程式碼的靈活度
2、泛型方法
public class Fun <K,V>{
//普通方法 可以使用 類中定義的泛型
public K method1(K k,V v){
return (K)null;
}
//普通方法 使用方法中定義的泛型
public <T> T method2(T t,V v){
return (T)null;
}
//在靜態方法中我們沒法使用 類中定義的泛型,想使用需自己定義<k>
public static <K> K method3(){
return null;
}
}
3、泛型介面
public interface CalGeneric <T> {
T add(T a,T b);
T sub(T a,T b);
T mul(T a,T b);
T div(T a,T b);
}
//實現類 - Integer
public class CalIntegerGeneric implements CalGeneric<Integer> {
@Override
public Integer add(Integer a, Integer b) {
return null;
}
@Override
public Integer sub(Integer a, Integer b) {
return null;
}
@Override
public Integer mul(Integer a, Integer b) {
return null;
}
@Override
public Integer div(Integer a, Integer b) {
return null;
}
}
//實現類 - Double
public class CalDoubleGeneric implements CalGeneric<Double>{
@Override
public Double add(Double a, Double b) {
return null;
}
@Override
public Double sub(Double a, Double b) {
return null;
}
@Override
public Double mul(Double a, Double b) {
return null;
}
@Override
public Double div(Double a, Double b) {
return null;
}
}