Java泛型的定义以及对于<? extends T>和<? super T>
Java 中对于泛型方法的定义:
public <T> T getT(){
.....相关代码;
}
其中我对<T>的理解就是申明只是一个泛型方法的标记,T是返回的类型。
对于泛型类的定义:
public class Type<T>{
....相关代码
}
上面写的是关于泛型方法和泛型类的定义。这里写这篇博客的主要目的是为了记录<? extends T> 和 <? super T>的理解。
<? extends T>是上界通配符。逻辑上来说,一个可以往里面放动物的容器,也可以往里面放狗,因为狗是继承了动物的,所以从
逻辑上来说,一个可以放狗的容器也应该是继承一个可以放动物的容器的。但是Java中这是不对的。这时候就需要上界通配符来解决这个问题。
可以定义一个Content<? extends Animal> content,这个content容器里面可以放任何Animal包括其子类。这使得容器Content之间也有
了一定的联系。但是其中的也有一定的副作用。Content类里面有个getContent()方法,这个方法是不会影响使用的。因为对java编译器来说,
里面所有的东西都有一个相同的父亲,那就是Animal。但是如果你想要使用setContent()方法,这时就会出现一个问题,问题是什么呢?那就
是我只知道里面的类型是Animal以及Animal的派生类,但是无法确定具体的类型,是Dog或者Cat等。这里的类型没有具体给明,所以编译器
在这里只是给了一个占位符,所以到后面往t里面放Dog或者Apple的时候他都不知道是不是和Animal相匹配,所以这是不允许使用set的。下面
方法中的 public void setContent(List<T> content) 如果想可以set T包括T的子类的List的时候,可以这么定义:
public void setContent(List<?extends T> content)。
<? super T>是下界通配符。其作用这好和上面的<? extends T>相反。Content<? super Animal> content 表示的是Animal 以及Animal
基类的容器,但不是Dog基类的容器。里面的setContent()方法是可以正常使用的。因为它规定了最小粒度的下限,那就是Animal。但是它往外面
getContent()就比较费劲,因为他们公共的基类只有Object。所以取出来的内容只能用Object来装。
所以这里总结了一点就是如果一个内容他需要set的内容比较多,那就使用<? super T>。如若使用get的多一点,那就使用<? extends T>。
下面是自己定义的一个Content类:
package test; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Content<T> { private String contentName; private List<T> content; private T t; private int size; public Content(){ content = new ArrayList<T>(); size = 0; } public String getContentName() { return contentName; } public void setContentName(String contentName) { this.contentName = contentName; } public List<T> getContent() { return content; } @SuppressWarnings("unchecked") public void setContent(List<? extends T> content) { this.content = (List<T>) content; } public void add(T content){ this.content.add(content); } public void getInfo(){ System.out.println(content.toString()); } public int getSize(){ size = content.size(); return size; } public T getT() { return t; } public void setT(T t) { this.t = t; } public void remove(int pos){ this.content.remove(pos); } public T get(int i){ if(i>content.size()) return null; return content.get(i); } }
定义的Animal类:
package test; public class Animal { private String type; private String describe; public Animal(){ } public Animal(String type,String describe){ this.type = type; this.describe = describe; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getDescribe() { return describe; } public void setDescribe(String describe) { this.describe = describe; } }
继承Animal的Dog类
package test; public class Dog extends Animal { private String name; private int age; public Dog(String type,String describe,String name,int age){ super(type,describe); 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; } }
浙公网安备 33010602011771号