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;//編譯通過(guò) ?? ??? ? ?? ??? ?Object[] arr1=new Object[10]; ?? ??? ?String arr2[]=new String[10]; ?? ??? ?arr1=arr2;//編譯通過(guò) ?? ??? ? ?? ??? ?//此時(shí)的list1和list2不具有子父類關(guān)系 ?? ??? ?List<Object> list1=null; ?? ??? ?List<String> list2=null; ?? ??? ? ?? ??? ?//編譯不通過(guò) ?? ??? ?list1=list2; ?? ??? ? ?? ??? ?show(list1); ?? ??? ?//編譯不通過(guò) ?? ??? ?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;//編譯通過(guò) list2=list3;//編譯通過(guò) }
通配符的使用
通配符?
類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;//編譯通過(guò) list=list2;//編譯通過(guò) print(list1);//編譯通過(guò) print(list2);//編譯通過(guò) } public void print(List<?> list) { Iterator<?> it=list.iterator(); while(it.hasNext()) { Object obj=it.next(); System.out.println(obj); } }
使用通配符后,數(shù)據(jù)的寫入和讀取要求
添加:對(duì)于List<?>就不能向其內(nèi)部添加數(shù)據(jù),除了添加null之外
獲?。涸试S讀取數(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; ?? ??? ?//添加:對(duì)于List<?>就不能向其內(nèi)部添加數(shù)據(jù)。 ?? ??? ?//除了添加null之外 ?? ??? ? ?? ??? ?list.add("DD"); //編譯不通過(guò) ?? ??? ?list.add("?");?? ?//編譯不通過(guò) ?? ??? ? ?? ??? ?list.add(null);?? ?//編譯通過(guò) ?? ??? ? ?? ??? ?//獲?。涸试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存儲(chǔ)的是A和A的子類
? super Person:
G<? super A>可以作為G<A>和G<B>的父類,其中,B是A的父類
G存儲(chǔ)的是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; //編譯通過(guò) ?? ??? ?list1=list4; //編譯通過(guò) ?? ??? ?list1=list5; //編譯不通過(guò) ?? ??? ? ?? ??? ?list2=list3; //編譯不通過(guò) ?? ??? ?list2=list4; //編譯通過(guò) ?? ??? ?list2=list5; //編譯通過(guò) ?? ??? ? ?? ??? ?//讀取數(shù)據(jù) ?? ??? ?list1=list3; ?? ??? ?Person p = list1.get(0); //編譯通過(guò) ?? ??? ?Student st=list1.get(0); //編譯不通過(guò) ?? ??? ? ?? ??? ?list2=list4; ?? ??? ?Object obj = list2.get(0); //編譯通過(guò) ?? ??? ?Person obj2=list2.get(0); //編譯不通過(guò) ?? ??? ? ?? ??? ?//寫入數(shù)據(jù) ?? ??? ?list1.add(new Student()); //編譯不通過(guò) ?? ??? ? ?? ??? ?list2.add(new Person()); //編譯通過(guò) ?? ??? ?list2.add(new Student()); //編譯通過(guò) ?? ?}
自定義泛型的測(cè)試
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類型對(duì)象到Map變量中 ?* public T get(String id):從map中獲取id對(duì)應(yīng)的對(duì)象 ?* public void update(String id,T entity):替換map中key為id的內(nèi)容,改為entity對(duì)象 ?* public List<T> list():返回map中存放的所有T對(duì)象 ?* public void delete (String id):刪除指定id對(duì)象 ?*? ?* @author CharlieLiang ?* @param <T> ?* ?*/ public class DAO<T> { ? ?? ?private Map<String,T> map; ?? ? ?? ?public DAO() { ?? ??? ?map=new HashMap<>(); ?? ?} ?? ? ?? ?//保存T類型對(duì)象到Map變量中 ?? ?public void save(String id ,T entity) { ?? ??? ?map.put(id, entity); ?? ?} ?? ? ?? ?//從map中獲取id對(duì)應(yīng)的對(duì)象 ?? ?public T get(String id) { ?? ??? ?return map.get(id); ?? ?} ?? ? ?? ?//替換map中key為id的內(nèi)容,改為entity對(duì)象 ?? ?public void update(String id,T entity) { ?? ??? ?if(map.containsKey(id)) { ?? ??? ??? ?map.put(id, entity); ?? ??? ?} ?? ?} ?? ? ?? ?//返回map中存放的所有T對(duì)象 ?? ?public List<T> list(){ ?? ??? ?//錯(cuò)誤的 //?? ??? ?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對(duì)象 ?? ?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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JAVA 截取字符串的三種方法 subString,StringUtils,split實(shí)例詳解
這篇文章給大家介紹JAVA 截取字符串的三種方法 subString,StringUtils,split,每種方法結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-12-12Spring Boot 2.x中Actuator的一些知識(shí)點(diǎn)
這篇文章主要給大家介紹了關(guān)于Spring Boot 2.x中Actuator的一些知識(shí)點(diǎn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring Boot 2.x具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09springcloud gateway自定義斷言規(guī)則詳解,以后綴結(jié)尾進(jìn)行路由
這篇文章主要介紹了springcloud gateway自定義斷言規(guī)則詳解,以后綴結(jié)尾進(jìn)行路由,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10Java實(shí)現(xiàn)LeetCode(1.兩數(shù)之和)
這篇文章主要介紹了Java實(shí)現(xiàn)LeetCode(兩數(shù)之和),本文使用java采用多種發(fā)放實(shí)現(xiàn)了LeetCode的兩數(shù)之和題目,需要的朋友可以參考下2021-06-06Java基于虹軟實(shí)現(xiàn)人臉識(shí)別、人臉比對(duì)、活性檢測(cè)等
本文主要介紹了Java基于虹軟實(shí)現(xiàn)人臉識(shí)別、人臉比對(duì)、活性檢測(cè)等,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02SpringBoot內(nèi)嵌Tomcat臨時(shí)目錄問(wèn)題及解決
這篇文章主要介紹了SpringBoot內(nèi)嵌Tomcat臨時(shí)目錄問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-04-04在java中實(shí)現(xiàn)C#語(yǔ)法里的按引用傳遞參數(shù)的方法
下面小編就為大家?guī)?lái)一篇在java中實(shí)現(xiàn)C#語(yǔ)法里的按引用傳遞參數(shù)的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-09-09MyBatis 延遲加載、一級(jí)緩存、二級(jí)緩存(詳解)
下面小編就為大家?guī)?lái)一篇MyBatis 延遲加載、一級(jí)緩存、二級(jí)緩存(詳解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08Java inputstream和outputstream使用詳解
這篇文章主要介紹了Java inputstream和outputstream使用詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08