泛型方法
定义语法
方法限定符 <类型参数列表> 返回值类型 方法名称(形参列表) {...}
示例
public class Test { //静态的泛型方法 需要在static后用<>声明泛型参数 public static <E> void swap(E[] array, int i, int j) { E t = array[i]; array[i] = array[j]; array[j] = t; } public static void main(String[] args) { //完成一个字符数组的倒转,注意这里的类型是包装类 Character[] arr = {'h', 'e', 'l', 'l', 'o'}; for(int i = 0; i < arr.length / 2; i++) { swap(arr, i, arr.length - 1 - i); } System.out.println(Arrays.toString(arr)); } }
运行结果:
通配符
? 用于在泛型的使用,即为通配符
通配符解决什么问题
class Message<T> { private T message; public T getMessage() { return message; } public void setMessage(T message) { this.message = message; } } public class Test1 { public static void main(String[] args) { Message<String> message = new Message<>(); message.setMessage("我不吃牛肉"); fun(message); } public static void fun(Message<String> temp) { System.out.println(temp.getMessage()); } }
以上程序会带来新的问题,如果现在泛型的类型设置不是String, 而是Integer.
public class Test1 { public static void main(String[] args) { Message<String> message = new Message<>(); message.setMessage(99); fun(message); } public static void fun(Message<String> temp) { System.out.println(temp.getMessage()); } }
我们需要的解决方案: 可以接收所有的泛型类型, 但又不能让用户随意修改.这种情况就需要使用通配符"?"来处理
范例:使用通配符
public class Test1 { public static void main(String[] args) { Message<String> message = new Message<>(); message.setMessage(99); fun(message); } //此时使用通配符"?"描述的是它可以接收任意类型,但是由于不确定类型,所以无法修改 public static void fun(Message<?> temp) { //temp.setMessage(100);无法修改! System.out.println(temp.getMessage()); } }
在"?"的基础上又产生了两个子通配符:
? extends 类: 设置通配符上限
? super 类: 设置了通配符下限
通配符上界
语法:
<? extends 上界>
<? extends Number> //可以传入的实参类型是Number或者Number的子类
举个栗子:
class Food { } class Fruit extends Food { } class Apple extends Fruit { } class Banana extends Fruit { } class Message<T> {//设置泛型 private T message; public T getMessage() { return message; } public void setMessage(T message) { this.message = message; } } public class Test2 { public static void main(String[] args) { Message<Apple> message = new Message<>(); message.setMessage(new Apple()); fun(message); Message<Apple> message2 = new Message<>(); message2.setMessage(new Banana()); fun(message2); } //此时使用通配符"?"描述的是它可以接收任意类型, 但是由于不确定类型, 所以无法修改 public static void fun(Message<? extends Fruit> temp) { //temp.setMessage(new Banana()); //仍然无法修改 //temp.setMessage(new Apple()); //仍然无法修改 System.out.println(temp.getMessage()); } }
此时无法在fun函数中对temp进行添加元素,因为temp接收的是Fruit和它的子类, 此时存储的元素应该是哪个子类无法确定.所以会添加报错!但是仍然可以获取元素.
//此时使用通配符"?"描述的是它可以接收任意类型, 但是由于不确定类型, 所以无法修改 public static void fun(Message<? extends Fruit> temp) { //temp.setMessage(new Banana()); //仍然无法修改 //temp.setMessage(new Apple()); //仍然无法修改 Fruit b = temp.getMessage(); System.out.println(b); }
通配符的上界, 不能写入数据, 只能进行读取数据.
通配符的下界
语法:
<? super 下界>
<? super Integer> //代表可以传入的实参的类型是Integer或者Integer的父类类型
class Food {} class Fruit extends Food {} class Apple extends Fruit {} class Plate<T> { private T plate; public T getPlate() { return plate; } public void setPlate(T plate) { this.plate = plate; } } public class Test { public static void main(String[] args) { } public static void fun(Plate<? super Fruit> temp) { //此时可以修改!添加的是Fruit或者是Fruit的子类 temp.setPlate(new Apple());//这个是Fruit的子类 temp.setPlate(new Fruit());//这个是Fruit本身 //Fruit fruit = temp.getPlate(); 不能直接接收,这里无法确定是哪个父类 System.out.println(temp.getPlate());//只能直接输出 } }
通配符的下界,不能进行读取数据,只能写入数据.