16(02)總結泛型
阿新 • • 發佈:2022-05-04
(1)泛型概述
是一種把明確型別的工作推遲到建立物件或者呼叫方法的時候才去明確的特殊的型別。
(2)格式:
<資料型別>
注意:該資料型別只能是引用型別。(類,介面,陣列)
(3)好處:
A:把執行時期的問題提前到了編譯期間
B:避免了強制型別轉換
C:優化了程式設計,解決了黃色警告線問題,讓程式更安全
package cn.itcast_01; import java.util.ArrayList; import java.util.Iterator; /* * ArrayList儲存字串並遍歷 * * 我們按照正常的寫法來寫這個程式, 結果確出錯了。 * 為什麼呢? * 因為我們開始儲存的時候,儲存了String和Integer兩種型別的資料。 * 而在遍歷的時候,我們把它們都當作String型別處理的,做了轉換,所以就報錯了。 * 但是呢,它在編譯期間卻沒有告訴我們。 * 所以,我就覺得這個設計的不好。 * 回想一下,我們的陣列 * String[] strArray = new String[3]; * strArray[0] = "hello"; * strArray[1] = "world"; * strArray[2] = 10; * 集合也模仿著陣列的這種做法,在建立物件的時候明確元素的資料型別。這樣就不會在有問題了。 * 而這種技術被稱為:泛型。 * * 泛型:是一種把型別明確的工作推遲到建立物件或者呼叫方法的時候才去明確的特殊的型別。引數化型別,把型別當作引數一樣的傳遞。 * 格式: * <資料型別> * 此處的資料型別只能是引用型別。 * 好處: * A:把執行時期的問題提前到了編譯期間 * B:避免了強制型別轉換 * C:優化了程式設計,解決了黃色警告線 */ public class GenericDemo { public static void main(String[] args) { // 建立 ArrayList<String> array = new ArrayList<String>(); // 新增元素 array.add("hello"); array.add("world"); array.add("java"); // array.add(new Integer(100)); //array.add(10); // JDK5以後的自動裝箱 // 等價於:array.add(Integer.valueOf(10)); // 遍歷 Iterator<String> it = array.iterator(); while (it.hasNext()) { // ClassCastException // String s = (String) it.next(); String s = it.next(); System.out.println(s); } // 看下面這個程式碼 // String[] strArray = new String[3]; // strArray[0] = "hello"; // strArray[1] = "world"; // strArray[2] = 10; } }
擴充套件題:
package cn.itcast_02; /** * 這是學生描述類 * * @author 風清揚 * @version V1.0 */ public class Student { // 姓名 private String name; // 年齡 private int age; public Student() { super(); } public Student(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } package cn.itcast_02; import java.util.ArrayList; import java.util.Iterator; /* * 需求:儲存自定義物件並遍歷。 * * A:建立學生類 * B:建立集合物件 * C:建立元素物件 * D:把元素新增到集合 * E:遍歷集合 */ public class ArrayListDemo2 { public static void main(String[] args) { // 建立集合物件 // JDK7的新特性:泛型推斷。 // ArrayList<Student> array = new ArrayList<>(); // 但是我不建議這樣使用。 ArrayList<Student> array = new ArrayList<Student>(); // 建立元素物件 Student s1 = new Student("曹操", 40); // 後知後覺 Student s2 = new Student("蔣幹", 30); // 不知不覺 Student s3 = new Student("諸葛亮", 26);// 先知先覺 // 新增元素 array.add(s1); array.add(s2); array.add(s3); // 遍歷 Iterator<Student> it = array.iterator(); while (it.hasNext()) { Student s = it.next(); System.out.println(s.getName() + "---" + s.getAge()); } System.out.println("------------------"); for (int x = 0; x < array.size(); x++) { Student s = array.get(x); System.out.println(s.getName() + "---" + s.getAge()); } } } (4)泛型的前世今生 A:泛型的由來 Object型別作為任意型別的時候,在向下轉型的時候,會隱含一個轉型問題 package cn.itcast_03; public class ObjectTool { private Object obj; public Object getObj() { return obj; } public void setObj(Object obj) { // Object obj = new Integer(30); this.obj = obj; } } package cn.itcast_03; /* * 早期的時候,我們使用Object來代表任意的型別。 * 向上轉型是沒有任何問題的,但是在向下轉型的時候其實隱含了型別轉換的問題。 * 也就是說這樣的程式其實並不是安全的。所以Java在JDK5後引入了泛型,提高程式的安全性。 */ public class ObjectToolDemo { public static void main(String[] args) { ObjectTool ot = new ObjectTool(); // 正常使用 ot.setObj(new Integer(27)); Integer i = (Integer) ot.getObj(); System.out.println("年齡是:" + i); ot.setObj(new String("林青霞")); String s = (String) ot.getObj(); System.out.println("姓名是:" + s); System.out.println("---------"); ot.setObj(new Integer(30)); // ClassCastException String ss = (String) ot.getObj(); System.out.println("姓名是:" + ss); } }
B:泛型類
package cn.itcast_04; /* * 泛型類:把泛型定義在類上 * 格式:public class 類名<資料型別,資料型別……>{} * <>中的資料型別 與呼叫型別一致 */ public class ObjectTool<T> { private T obj; public T getObj() { return obj; } public void setObj(T obj) { this.obj = obj; } } package cn.itcast_04; /* * 泛型類的測試 */ public class ObjectToolDemo { public static void main(String[] args) { // ObjectTool ot = new ObjectTool(); // // ot.setObj(new String("風清揚")); // String s = (String) ot.getObj(); // System.out.println("姓名是:" + s); // // ot.setObj(new Integer(30)); // Integer i = (Integer) ot.getObj(); // System.out.println("年齡是:" + i); // ot.setObj(new String("林青霞")); // // ClassCastException // Integer ii = (Integer) ot.getObj(); // System.out.println("姓名是:" + ii); System.out.println("-------------"); ObjectTool<String> ot = new ObjectTool<String>(); // ot.setObj(new Integer(27)); //這個時候編譯期間就過不去 ot.setObj(new String("林青霞")); String s = ot.getObj(); System.out.println("姓名是:" + s); ObjectTool<Integer> ot2 = new ObjectTool<Integer>(); // ot2.setObj(new String("風清揚"));//這個時候編譯期間就過不去 ot2.setObj(new Integer(27)); Integer i = ot2.getObj(); System.out.println("年齡是:" + i); } }
C:泛型方法
package cn.itcast_05;
//public class ObjectTool<T> {
// // public void show(String s) {
// // System.out.println(s);
// // }
// //
// // public void show(Integer i) {
// // System.out.println(i);
// // }
// //
// // public void show(Boolean b) {
// // System.out.println(b);
// // }
//
// public void show(T t) {
// System.out.println(t);
// }
// }
/*
* 泛型方法:把泛型定義在方法上
* 格式:public<資料型別>返回值型別 方法名(資料型別 變數名){};
*/
public class ObjectTool {
public <T> void show(T t) {
System.out.println(t);
}
}
package cn.itcast_05;
public class ObjectToolDemo {
public static void main(String[] args) {
// ObjectTool ot = new ObjectTool();
// ot.show("hello");
// ot.show(100);
// ot.show(true);
// ObjectTool<String> ot = new ObjectTool<String>();
// ot.show("hello");
//
// ObjectTool<Integer> ot2 = new ObjectTool<Integer>();
// ot2.show(100);
//
// ObjectTool<Boolean> ot3 = new ObjectTool<Boolean>();
// ot3.show(true);
// 如果還聽得懂,那就說明泛型類是沒有問題的
// 但是呢,誰說了我的方法一定要和類的型別的一致呢?
// 我要是類上沒有泛型的話,方法還能不能接收任意型別的引數了呢?
// 定義泛型方法後
ObjectTool ot = new ObjectTool();
ot.show("hello");
ot.show(100);
ot.show(true);
}
}
D:泛型介面
package cn.itcast_06;(1)
/*
* 泛型介面:把泛型定義在介面上
* 格式: public interface 介面名<資料型別,資料型別,……>{}
*
*/
public interface Inter<T> {
public abstract void show(T t);
}
package cn.itcast_06;(2)
public class InterDemo {
public static void main(String[] args) {
// 第一種情況的測試
// Inter<String> i = new InterImpl();
// i.show("hello");
// // 第二種情況的測試
Inter<String> i = new InterImpl<String>();
i.show("hello");
Inter<Integer> ii = new InterImpl<Integer>();
ii.show(100);
}
}
package cn.itcast_06;(3)
//實現類在實現介面的時候
//第一種情況:已經知道該是什麼型別的了(明確子類的資料型別)
//public class InterImpl implements Inter<String> {
//
// @Override
// public void show(String t) {
// System.out.println(t);
// }
// }
//第二種情況:還不知道是什麼型別的(把子類定義成泛型)
public class InterImpl<T> implements Inter<T> {
@Override
public void show(T t) {
System.out.println(t);
}
}
E:泛型高階萬用字元
?
? extends E
? super E
package cn.itcast_07;
import java.util.ArrayList;
import java.util.Collection;
/*
* 泛型高階(萬用字元)
* ? :任意型別,如果沒有明確,那麼就是Object以及任意的Java類了
* ? extends E:向下限定,E或E的子類
* ? super E :向上限定,E或E的父類
*/
public class GenericDemo {
public static void main(String[] args) {
// 泛型如果明確的寫的時候,前後必須一致
Collection<Object> c1 = new ArrayList<Object>();
// Collection<Object> c2 = new ArrayList<Animal>();
// Collection<Object> c3 = new ArrayList<Dog>();
// Collection<Object> c4 = new ArrayList<Cat>();
// ?表示任意的型別都是可以的
Collection<?> c5 = new ArrayList<Object>();
Collection<?> c6 = new ArrayList<Animal>();
Collection<?> c7 = new ArrayList<Dog>();
Collection<?> c8 = new ArrayList<Cat>();
// ? extends E:向下限定,E及其子類
// Collection<? extends Animal> c9 = new ArrayList<Object>();
Collection<? extends Animal> c10 = new ArrayList<Animal>();
Collection<? extends Animal> c11 = new ArrayList<Dog>();
Collection<? extends Animal> c12 = new ArrayList<Cat>();
// ? super E:向上限定,E極其父類
Collection<? super Animal> c13 = new ArrayList<Object>();
Collection<? super Animal> c14 = new ArrayList<Animal>();
// Collection<? super Animal> c15 = new ArrayList<Dog>();
// Collection<? super Animal> c16 = new ArrayList<Cat>();
}
}
class Animal {
}
class Dog extends Animal {
}
class Cat extends Animal {
}
(5)我們在哪裡使用呢?
一般是在集合中使用。
package cn.itcast_02;
/**
* 這是學生描述類
*
* @author 風清揚
* @version V1.0
*/
public class Student {
// 姓名
private String name;
// 年齡
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package cn.itcast_02;
import java.util.ArrayList;
import java.util.Iterator;
/*
* 泛型在哪些地方使用呢?
* 看API,如果類,介面,抽象類後面跟的有<E>就說要使用泛型。一般來說就是在集合中使用。
*/
public class ArrayListDemo {
public static void main(String[] args) {
// 用ArrayList儲存字串元素,並遍歷。用泛型改進程式碼
ArrayList<String> array = new ArrayList<String>();
array.add("hello");
array.add("world");
array.add("java");
Iterator<String> it = array.iterator();
while (it.hasNext()) {
String s = it.next();
System.out.println(s);
}
System.out.println("-----------------");
for (int x = 0; x < array.size(); x++) {
String s = array.get(x);
System.out.println(s);
}
}
}