1、泛型的优势
1)多种数据类型执行相同代码
计算两个数据的和,并返回计算结果(double)型:
public <T extends Number> double addNumbers(T a,T b){
System.out.println(a+" + "+b +" = "+ (a.doubleValue()+b.doubleValue()));
return (a.doubleValue()+b.doubleValue());
}
2)避免强制类型转换
在编译期需要指定数据的类型,避免在代码中出现强制类型转换,导致运行时的出错。
2、类使用泛型
类对于泛型的使用比较简单:
class A<T>{
public T getT(T t){
return t;
}
}
如果是多个类型:
class B<K,V,P>{ …… }
3、接口使用泛型
public interface C<K,V>{
public K deal();
}
4、泛型方法
典型方法:
/**
* 泛型方法
* @param data 入参的类型也为T (可以改动)
* @param <T> 指定方法持有一个类型T(或者说是个泛型方法)(这里是必需的)
* @return 需要返回值,返回值类型也为 T (可以改动)
*/
public <T> T testMethod(T t){
return t;
}
5、泛型上下边界及通配符
1)上边界
<T extends Fruit> //继承自 Fruit的所有类,Fruit 可以为类也可以为接口
2)下边界
<T super Apple> //Apple及Apple的所有父类(包括接口),可以传入
3)通配符
<? extends Fruit> 或者 class A<?>{}
6、示例
基础类:
//顶级父类
class Fruit{
private String type;
public void setType(String type){
this.type=type;
}
public String getType(){
return type;
}
public String taste(){
return "I hava no taste!";
}
}
//接口,行为
interface FruitAction{
public void death();
}
//第一个子类
class Apple extends Fruit implements FruitAction{
{
setType("Apple");
}
public String taste(){
return "I taste sweet!";
}
public void death(){
System.out.println("Oh! I am going to die!["+getType()+"]");
}
}
//第二个子类
class Banana extends Fruit{
{
setType("Banana");
}
public String taste(){
return "I taste good!";
}
}
//第三个子类
class Orange extends Fruit{
{
setType("Orange");
}
public String taste(){
return "I taste Acid!";
}
}
泛型类:
//果盘,聚合了多个水果
class FruitPie<K extends Fruit,V extends Fruit,P extends Fruit>{
private int kCount;
private int vCount;
private int pCount;
private K k;
private V v;
private P p;
public void addK(){
kCount++;
}
public void addV(){
vCount++;
}
public void addP(){
pCount++;
}
public FruitPie(K k,V v,P p){
this.k = k;
this.v = v;
this.p = p;
}
public void getPieInfo(){
System.out.println("I have "+k.getType()+"[num="+kCount+"],"+v.getType()+"[num="+vCount+"],"+p.getType()+"[num="+pCount+"]");
}
}
验证:
public class Test {
//泛型方法
public <T extends Fruit> T saySomething(T data){
System.out.println("I am "+data.getType()+" ,"+data.taste());
return data;
}
//泛型方法 (接口作为上边界)
public <T extends FruitAction> void action(T t){
t.death();
}
public static void main(String[] args) {
Test t = new Test();
Apple a = new Apple();
//测试泛型方法
Apple b1 = t.saySomething(a);
System.out.println("I am still "+b1.getType());
//测试 上边界为接口 的泛型方法
t.action(b1);
Banana b= new Banana();
Orange c = new Orange();
//多类型泛型使用
FruitPie<Apple,Banana,Orange> pie = new FruitPie<Apple,Banana,Orange>(a,b,c);
pie.addK();
pie.addV();pie.addV();
pie.addP();pie.addP();pie.addP();
pie.getPieInfo();
}
}