Java泛型通配符的使用詳解
泛型在繼承方面的體現(xiàn)
類A是類B的父類,G<A>和G<B>二者不具有子父類關(guān)系,二者是并列關(guān)系
@Test ?? ?public void test1() { ?? ??? ?Object obj=null; ?? ??? ?String str=null; ?? ??? ?obj=str;//編譯通過 ?? ??? ? ?? ??? ?Object[] arr1=new Object[10]; ?? ??? ?String arr2[]=new String[10]; ?? ??? ?arr1=arr2;//編譯通過 ?? ??? ? ?? ??? ?//此時的list1和list2不具有子父類關(guān)系 ?? ??? ?List<Object> list1=null; ?? ??? ?List<String> list2=null; ?? ??? ? ?? ??? ?//編譯不通過 ?? ??? ?list1=list2; ?? ??? ? ?? ??? ?show(list1); ?? ??? ?//編譯不通過 ?? ??? ?show(list2); ?? ?} ?? ? ?? ?public void show(List<Object> list) { ?? ??? ? ?? ?}
類A是類B的父類,A<G>是B<G>的父類
@Test public void test2() { AbstractList<String> list1=null; List<String> list2=null; ArrayList<String>list3=null; list1=list3;//編譯通過 list2=list3;//編譯通過 }
通配符的使用
通配符?
類A是類B的父類,G<A>和G<B>是沒有關(guān)系的,二者共同父類是:G<?>
@Test public void test4() { List<Object> list1=null; List<String> list2=null; List<?> list=null; list=list1;//編譯通過 list=list2;//編譯通過 print(list1);//編譯通過 print(list2);//編譯通過 } public void print(List<?> list) { Iterator<?> it=list.iterator(); while(it.hasNext()) { Object obj=it.next(); System.out.println(obj); } }
使用通配符后,數(shù)據(jù)的寫入和讀取要求
添加:對于List<?>就不能向其內(nèi)部添加數(shù)據(jù),除了添加null之外
獲取:允許讀取數(shù)據(jù),讀取的數(shù)據(jù)類型為Object
@Test ?? ?public void test5() { ?? ??? ?List<?> list=null; ?? ??? ?List<String> list3=new ArrayList<>(); ?? ??? ?list3.add("AAA"); ?? ??? ?list3.add("BBB"); ?? ??? ?list3.add("CCC"); ?? ??? ? ?? ??? ?list=list3; ?? ??? ?//添加:對于List<?>就不能向其內(nèi)部添加數(shù)據(jù)。 ?? ??? ?//除了添加null之外 ?? ??? ? ?? ??? ?list.add("DD"); //編譯不通過 ?? ??? ?list.add("?");?? ?//編譯不通過 ?? ??? ? ?? ??? ?list.add(null);?? ?//編譯通過 ?? ??? ? ?? ??? ?//獲?。涸试S讀取數(shù)據(jù),讀取的數(shù)據(jù)類型為Object ?? ??? ?Object obj = list.get(0); ?? ??? ?System.out.println(obj); ?? ?}
有限制條件的通配符的使用
? extends A:
G<? extends A>可以作為G<A>和G<B>的父類,其中,B是A的子類
G存儲的是A和A的子類
? super Person:
G<? super A>可以作為G<A>和G<B>的父類,其中,B是A的父類
G存儲的是A和A的父類
@Test ?? ?public void test6() { ?? ??? ?List<? extends Person> list1=null; ?? ??? ?List<? super Person> list2=null; ?? ??? ? ?? ??? ?List<Student> list3=new ArrayList<>(); ?? ??? ?List<Person> list4=new ArrayList<>();; ?? ??? ?List<Object> list5=new ArrayList<>();; ?? ??? ? ?? ??? ?list1=list3; //編譯通過 ?? ??? ?list1=list4; //編譯通過 ?? ??? ?list1=list5; //編譯不通過 ?? ??? ? ?? ??? ?list2=list3; //編譯不通過 ?? ??? ?list2=list4; //編譯通過 ?? ??? ?list2=list5; //編譯通過 ?? ??? ? ?? ??? ?//讀取數(shù)據(jù) ?? ??? ?list1=list3; ?? ??? ?Person p = list1.get(0); //編譯通過 ?? ??? ?Student st=list1.get(0); //編譯不通過 ?? ??? ? ?? ??? ?list2=list4; ?? ??? ?Object obj = list2.get(0); //編譯通過 ?? ??? ?Person obj2=list2.get(0); //編譯不通過 ?? ??? ? ?? ??? ?//寫入數(shù)據(jù) ?? ??? ?list1.add(new Student()); //編譯不通過 ?? ??? ? ?? ??? ?list2.add(new Person()); //編譯通過 ?? ??? ?list2.add(new Student()); //編譯通過 ?? ?}
自定義泛型的測試
User類
public class User { ? ?? ?@Override ?? ?public int hashCode() { ?? ??? ?final int prime = 31; ?? ??? ?int result = 1; ?? ??? ?result = prime * result + age; ?? ??? ?result = prime * result + id; ?? ??? ?result = prime * result + ((name == null) ? 0 : name.hashCode()); ?? ??? ?return result; ?? ?} ?? ?@Override ?? ?public boolean equals(Object obj) { ?? ??? ?if (this == obj) ?? ??? ??? ?return true; ?? ??? ?if (obj == null) ?? ??? ??? ?return false; ?? ??? ?if (getClass() != obj.getClass()) ?? ??? ??? ?return false; ?? ??? ?User other = (User) obj; ?? ??? ?if (age != other.age) ?? ??? ??? ?return false; ?? ??? ?if (id != other.id) ?? ??? ??? ?return false; ?? ??? ?if (name == null) { ?? ??? ??? ?if (other.name != null) ?? ??? ??? ??? ?return false; ?? ??? ?} else if (!name.equals(other.name)) ?? ??? ??? ?return false; ?? ??? ?return true; ?? ?} ?? ?@Override ?? ?public String toString() { ?? ??? ?return "User [id=" + id + ", age=" + age + ", name=" + name + "]"; ?? ?} ?? ?public int getId() { ?? ??? ?return id; ?? ?} ?? ?public void setId(int id) { ?? ??? ?this.id = id; ?? ?} ?? ?public int getAge() { ?? ??? ?return age; ?? ?} ?? ?public void setAge(int age) { ?? ??? ?this.age = age; ?? ?} ?? ?public String getName() { ?? ??? ?return name; ?? ?} ?? ?public void setName(String name) { ?? ??? ?this.name = name; ?? ?} ?? ?public User() { ?? ??? ? ?? ?} ?? ?private int id; ?? ?public User(int id, int age, String name) { ?? ??? ?super(); ?? ??? ?this.id = id; ?? ??? ?this.age = age; ?? ??? ?this.name = name; ?? ?} ?? ?private int age; ?? ?private String name; }
DAO類
import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; ? /** ?* 定義泛型類DAO<T> ?* 創(chuàng)建一下方法 ?* public void save(String id ,T entity):保存T類型對象到Map變量中 ?* public T get(String id):從map中獲取id對應(yīng)的對象 ?* public void update(String id,T entity):替換map中key為id的內(nèi)容,改為entity對象 ?* public List<T> list():返回map中存放的所有T對象 ?* public void delete (String id):刪除指定id對象 ?*? ?* @author CharlieLiang ?* @param <T> ?* ?*/ public class DAO<T> { ? ?? ?private Map<String,T> map; ?? ? ?? ?public DAO() { ?? ??? ?map=new HashMap<>(); ?? ?} ?? ? ?? ?//保存T類型對象到Map變量中 ?? ?public void save(String id ,T entity) { ?? ??? ?map.put(id, entity); ?? ?} ?? ? ?? ?//從map中獲取id對應(yīng)的對象 ?? ?public T get(String id) { ?? ??? ?return map.get(id); ?? ?} ?? ? ?? ?//替換map中key為id的內(nèi)容,改為entity對象 ?? ?public void update(String id,T entity) { ?? ??? ?if(map.containsKey(id)) { ?? ??? ??? ?map.put(id, entity); ?? ??? ?} ?? ?} ?? ? ?? ?//返回map中存放的所有T對象 ?? ?public List<T> list(){ ?? ??? ?//錯誤的 //?? ??? ?Collection<T> values = map.values(); //?? ??? ?return (List<T>) values; ?? ??? ?//正確的 ?? ??? ?List<T> list=new ArrayList<>(); ?? ??? ?Collection<T> values = map.values(); ?? ??? ?for(T t:values) { ?? ??? ??? ?list.add(t); ?? ??? ?} ?? ??? ?return list; ?? ?} ?? ? ?? ?//刪除指定id對象 ?? ?public void delete (String id) { ?? ??? ?map.remove(id); ?? ?} }
DAOTest
import java.util.List; ? import org.junit.jupiter.api.Test; ? public class DAOTest { ? ?? ?@Test ?? ?public void testList() { ?? ??? ?DAO<User> dao = new DAO<>(); ?? ??? ?dao.save("1001", new User(1001,34,"周杰倫")); ?? ??? ?dao.save("1002", new User(1002,20,"昆凌")); ?? ??? ?dao.save("1003", new User(1002,20,"蔡依林")); ?? ??? ? ?? ??? ?List<User> list = dao .list(); ?? ??? ?list.forEach( i->System.out.println(i)); ?? ??? ? ?? ?} ?? ? ?? ?@Test ?? ?public void testUpdate() { ?? ??? ?DAO<User> dao = new DAO<>(); ?? ??? ?dao.save("1001", new User(1001,34,"周杰倫")); ?? ??? ?dao.save("1002", new User(1002,20,"昆凌")); ?? ??? ?dao.save("1003", new User(1002,20,"蔡依林")); ?? ??? ? ?? ??? ?dao.update("1003", new User(1003,40,"方文山")); ?? ??? ? ?? ??? ?List<User> list=dao.list(); ?? ??? ?list.forEach(i->System.out.println(i)); ?? ?} ?? ? ?? ?@Test ?? ?public void testDelete() { ?? ??? ?DAO<User> dao = new DAO<>(); ?? ??? ?dao.save("1001", new User(1001,34,"周杰倫")); ?? ??? ?dao.save("1002", new User(1002,20,"昆凌")); ?? ??? ?dao.save("1003", new User(1002,20,"蔡依林")); ?? ??? ? ?? ??? ?dao.delete("1003"); ?? ??? ? ?? ??? ?List<User> list=dao.list(); ?? ??? ?list.forEach(i->System.out.println(i)); ?? ?} }
到此這篇關(guān)于Java泛型通配符的使用詳解的文章就介紹到這了,更多相關(guān)Java泛型通配符內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JAVA 截取字符串的三種方法 subString,StringUtils,split實例詳解
這篇文章給大家介紹JAVA 截取字符串的三種方法 subString,StringUtils,split,每種方法結(jié)合實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-12-12Spring Boot 2.x中Actuator的一些知識點
這篇文章主要給大家介紹了關(guān)于Spring Boot 2.x中Actuator的一些知識點,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用Spring Boot 2.x具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09springcloud gateway自定義斷言規(guī)則詳解,以后綴結(jié)尾進行路由
這篇文章主要介紹了springcloud gateway自定義斷言規(guī)則詳解,以后綴結(jié)尾進行路由,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10Java實現(xiàn)LeetCode(1.兩數(shù)之和)
這篇文章主要介紹了Java實現(xiàn)LeetCode(兩數(shù)之和),本文使用java采用多種發(fā)放實現(xiàn)了LeetCode的兩數(shù)之和題目,需要的朋友可以參考下2021-06-06Java基于虹軟實現(xiàn)人臉識別、人臉比對、活性檢測等
本文主要介紹了Java基于虹軟實現(xiàn)人臉識別、人臉比對、活性檢測等,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02SpringBoot內(nèi)嵌Tomcat臨時目錄問題及解決
這篇文章主要介紹了SpringBoot內(nèi)嵌Tomcat臨時目錄問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-04-04在java中實現(xiàn)C#語法里的按引用傳遞參數(shù)的方法
下面小編就為大家?guī)硪黄趈ava中實現(xiàn)C#語法里的按引用傳遞參數(shù)的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-09-09Java inputstream和outputstream使用詳解
這篇文章主要介紹了Java inputstream和outputstream使用詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-08-08