泛型
-
泛型的本质:参数类型化
-
概述:将类型由原来的具体的类型参数化,然后在 使用/调用 时传入具体的类型
-
格式:
- <类型>
- 指定一种类型的格式,这里的类型可以看成是 方法中的形参(如果不理解可去看下形参和实参)
- 并且 类型 只能是 引用类型,不能是基本数据类型
- <类型>
-
好处:
-
把运行时期的问题提前到了编译期间
import java.util.ArrayList; import java.util.Collection;public class Test{// 遍历集合public static void show(Collection co){for(Object c : co){System.out.println(c);}}public static void main(String args[]){// 1、创建集合对象,Collection 是接口,所以创建对象只能用其子类实现类Collection c = new ArrayList();// 2、添加元素c.add(1);c.add("张三");c.add(true);// 3、遍历集合show(c);} }
注意:我们可以看到,此时的 Collection 集合可以添加任意数据类型,但是大家思考一个问题,集合中存储不同数据类型,是否会影响我们后期对于集合中数据的操作呢?答案是肯定的,怎么解决呢,我们就可用到泛型。
这样,我们就可以将 问题 提前到了 编译期间!
-
避免了强制类型转换
-
泛型类
-
格式: 修饰符 class 类名<参数类型>{}
// 学生泛型类 class Student<T>{private T value; // 定义私有变量public Student(T value){this.value = value;}public T getValue(){return value;}public void setValue(T value){this.value = value;} } // 测试类 public class Test1{public static void main(String args[]){// 这里的 <> 中 String 和 Integer 是实参,T 是形参Student<String> s1 = new Student<String>("张三");Student<Integer> s2 = new Student<Integer>(1);System.out.println(s1.getValue() + " " + s2.getValue());} }
最终运行结果:张三 1
泛型方法
-
格式:修饰符 <类型> 返回值类型 方法名(类型 变量名){}
class Cat{// 泛型方法public <T> T show(T t){return t;} } public class Test{public static void main(String args[]){// 1、创建对象Cat t = new Cat();// 2、调用泛型方法,传入不同的参数String s = t.show("张三");int i = t.show(1);System.out.println(s + " " + i);} }
最终运行结果:张三 1
泛型接口
-
格式:修饰符 interface 接口名 <类型>{}
interface Animal<T>{// 抽象方法public void show(T t); }// 实现 泛型接口 class Dog implements Animal<String>{@Overridepublic void show(String s) {System.out.println(s);} }public class Test{public static void main(String[] args) {Dog d = new Dog();d.show("李四");} }
类型通配符
-
类型通配符:<?>
-
例如:List<?>:表示元素类型未知的List,他的元素可以匹配任何的类型
这种带通配符的List仅表示它是各种泛型的List的父类,并不能把元素添加到其中
范围 格式 举例 作用 任意类型 <?> List<?> 表示的类型是所有 上限 <? extends 类型> List<? extends Number> 表示的类型是Number或者其子类 下限 <? super 类型> List<? super Number> 表示的类型是Number或者其父类