Java泛型使用总结

Java泛型和通配符解决了类型参数化的问题,使用主要有如下几种组合:

 泛型 通配符同时使用泛型加+通配符
定义类 不可使用不可用
定义方法   

1.在定义类时使用泛型:

泛型占位符<T>位于类名之后,左花括号之前,表明这是一个泛型类,格式如下:

类修饰符 类名 <T> {
}

例如:

class Demo1<T>{
	T field;
	public T getField(){
		return this.field;
	}
	public void setField(T t){
		this.field = t;
	}
}
	
public class Main {
	public static void main(String[] args){
	    Demo1<String> demo = new Demo1<String>();
            demo.setField("定义泛型类");
            System.out.println(demo.getField());
	}
}

2.在定义方法是使用泛型:

在普通类和泛型类中都可以定义泛型方法,格式是(<T>为泛型占位符):

分为如下几种:

(1)无返回值,无形参方法:

方法修饰符 <T> 方法返回值 方法名(){}

(2)无返回值,有形参方法:

方法修饰符 <T> 方法返回值 方法名(T t){}

(3)有返回值,有形参方法:

方法修饰符 <T> Class<T> 方法名(){}

(4)有返回值,有形参方法:

方法修饰符 <T> Class<T> 方法名(T t){}

举例说明:

class Demo1<T>{
	T field;
	public T getField(){
		return this.field;
	}
	public void setField(T t){
		this.field = t;
	}
	//无返回值无参数泛型方法
	public <E> void printClass(){
		ArrayList<E> al = new ArrayList<E>();
		System.out.print("执行无返回值无参数泛型方法");
		System.out.println(al.getClass());
	}
	//无返回值有参数泛型方法
	public <E> void printClass2(E e){
		System.out.print("执行无返回值有参数泛型方法");
		System.out.println(e.getClass());
	}
	//有返回值无参数泛型方法
	public <E> ArrayList<E> newArray(){
		System.out.println("执行有返回值无参数泛型方法");
		return new ArrayList<E>();
	}
	//有返回值有参数泛型方法
	public <E> ArrayList<E> newArray2(E e){
		System.out.println("执行有返回值有参数泛型方法");
		return new ArrayList<E>();
	}
}

public class Main {
	public static void main(String[] args){
		Demo1<String> demo = new Demo1<String>();
		demo.printClass();
		demo.printClass2("执行有泛型形参无返回值");
		demo.newArray();
		demo.newArray2("执行有泛型形参有返回值");
	}
}

执行结果:

执行无返回值无参数泛型方法class java.util.ArrayList
执行无返回值有参数泛型方法class java.lang.String
执行有返回值无参数泛型方法
执行有返回值有参数泛型方法

在定义方法时使用泛型可以使用extends关键字指定泛型的上界,例如:

class Demo {
    public <T extends Number> void showClass(T t) {
        System.out.println(t.getClass());
    }
}
 
public class Test {     
    public static void main (String[] args) throws java.lang.Exception
    {
        Demo demo = new Demo();
        demo.showClass(123);
        demo.showClass(123f);
        demo.showClass(123L);
        // demo.showClass("123"); 有错误 参数的类型,只能是 Number类型或者其子类
    }
}

3.在定义方法时使用通配符?:

class Demo {
    public void show(List<?> list) {
    	//只能往list里面添加null
        list.add(null);
        //list.add(123); 编译错误
	//list.add(new Object());编译错误
        for (Object object:list) {
            System.out.println(object);
        }
    }
}
public class Main {
	public static void main(String[] args){
              Demo demo = new Demo();
              List<Integer> listInt = new ArrayList<Integer>();
              listInt.add(123);
              demo.show(listInt);
              List<String> listStr = new ArrayList<String>();
              listStr.add("字符串");
              demo.show(listStr);
	}
}

注意:

由于程序无法确认list中的元素类型,所以不能向其中添加对象,连Object类型都不行.除了null(null是所有引用类型的示例)

5.在定义方法时同时使用泛型加通配符:

一般用 extends/super关键字分别指定形参类型的上界/下界(包含上界/下界):

public class Main {
    public static <T> void copy0(List<T> src,List<T> dest){
    	for(T t:src){
    		dest.add(t);
    	}
    }
    
    public static <T> void copy1(List<T> src,List<? super T> dest){
    	for(T t:src){
    		dest.add(t);
    	}
    }
    
    public static <T> void copy2(List<? extends T> src,List<T> dest){
    	for(T t:src){
    		dest.add(t);
    	}
    }
    
	public static void main(String[] args){
		List<Integer> srcList = new ArrayList<Integer>();
		List<Integer> destList0 = new ArrayList<Integer>();
		List<Number> destList1 = new ArrayList<Number>();
		List<Number> destList2 = new ArrayList<Number>();
		srcList.add(1);
		srcList.add(23);
		srcList.add(456);
		copy0(srcList,destList0);
		copy1(srcList,destList1);
		copy2(srcList,destList2);
		System.out.println("destList0[0]" + destList0.get(0));
		System.out.println("destList1[1]:" + destList1.get(1));
		System.out.println("destList2[2]:" + destList2.get(2));
	}
}

最后说一下泛型数组:

数组元素不能包含类型变量或类型形参;

    //不允许定义这样的数组
    //List<String>[] lsa = new ArrayList<String>[10];

但可以声明元素类型包含类型变量或类型形参的数组:

    //允许这样声明数组
    List<String>[] lsa = new ArrayList[10];

也可以使用通配符声明数组;

    //也可以使用通配符声明数组
    List<?>[] lsa = new ArrayList<?>[10];

但在使用中要注意使用instanceof运算符来保证数据类型.

待续.

本文部分参考于:

https://www.bo56.com/java%E6%B3%9B%E5%9E%8B%E4%BD%BF%E7%94%A8%E7%A4%BA%E4%BE%8B%E6%95%B4%E7%90%86/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值