开发者

Java泛型通配符的使用详解

目录
  • 泛型在继承方面的体现
  • 通配符的使用
  •  有限制条件的通配符的使用
  • 自定义泛型的测试

泛型在继承方面的体现

类A是类B的父类,G<A>和G<B>二者不具有子父类关系,二者是并列关系

@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不具有子父类关系
  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=nujavascriptll;
        
        list1=list3;//编译通过
        list2=list3;//编译通过
    }

通配符的使用

通配符?

类A是类B的父类,G<A>和G<B>是没有关系的,二者共同父类是: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);
        }
    }

使用通配符后,数据的写入和读取要求

添加:对于List<?>就不能向其内部添加数据,除了添加null之外

获取:允许读取数据,读取的数据类型为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<?>就不能向其内部添加数据。
  //除了添加null之外
  
  list.add("DD"); //编译不通过
  list.add("?"); //编译不通过
  
  list.add(null); //编译通过
  
  //获取:允许读取数据,读取的数据类型为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=lphpist4; //编译通过
  list1=list5; //编译不通过
  
  list2=list3; //编译不通过
  list2=list4; //编译通过
  list2=list5; //编译通过
  
  //读取数据
  list1=list3;
  Person p = list1.get(0); //编译通过
  Student st=list1.get(0); //编译不通过
  
  list2=list4;
  Object obj = list2.get(0); //编译通过
  Person obj2=list2.get(0); //编译不通过
  
  //写入数据
  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)
    开发者_JAVA入门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>
* 创建一下方法
* public void save(String id ,T entity):保存T类型对象到Map变量中
* public T get(String id):从map中获取id对应的对象
* public void update(String id,T entity):替换map中key为id的内容,改为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对应的对象
 public T get(String id) {
  return map.get(id);
 }
 
 //替换map中key为id的内容,改为entity对象
 public void update(String id,T entity) {
  if(map.containsKey(id)) {
   map.put(id, entity);
  }
 }
 
 //返回mhttp://www.devze.comap中存放的所有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));
 }
}

到此这篇关于Java泛型通配符的使用详解的文章就介绍到这了,更多相关Java泛型通配符内容请搜索我们以前的文章或继续浏览下编程面的相关文章希望大家以后多多支持我们!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新开发

开发排行榜