泛型:
本质上是一个参数化类型
// 指定能够存放的数据类型,统一类型,防止出现类型转换异常
List<String> list = new ArrayList<>();
list.add("111");
泛型的擦除:
泛型只在编译阶段有效,在编译只有,jvm会采取去泛型化的措施,在运行阶段没有效果
实例:
public static void main(String[] args) throws Exception {
// 指定能够存放的数据类型,统一类型,防止出现类型转换异常
List<String> list = new ArrayList<>();
list.add("111");
list.add("xiaohong");
list.add("56665");
//使用反射的方式,跳过编译直接执行方法
Class<? extends List> aClass = list.getClass();
Method method = aClass.getDeclaredMethod("add",Object.class);
method.invoke(list,new Object());
System.out.println(list);
}
运行程序得到结果如下:
[111, xiaohong, 56665, java.lang.Object@4554617c]
泛型通配符的介绍:
无边界通配符
? 表示都能满足条件
public static void main(String[] args) throws Exception {
List<String> list = new ArrayList<>();
list.add("121212");
list.add("qqqq");
list.add("89dk");
loop(list);
}
public static void loop(List<?> list){
for (Object o : list) {
System.out.println(o);
}
}
上边界通配符
? extend Number 代表从number往下的之类都能满足条件
public static void main(String[] args) throws Exception {
List<Number> list2 = new ArrayList<>();
list2.add(111);
list2.add(222);
list2.add(333);
loop2(list2);
}
public static void loop2(List<? extends Number> list){
for (Object o : list) {
System.out.println(o);
}
}
下边界通配符
? super Integer
通用类型必须是Integer到Object的父类
List<Number> list2 = new ArrayList<>();
list2.add(111);
list2.add(222);
list2.add(333);
loop3(list2);
}
public static void loop3(List<? super Number> list){
for (Object o : list) {
System.out.println(o);
}
}
泛型的使用
规则:必须先声明再使用
泛型的声明是通过<>实现的,约定泛型可以使用单个大写字母表示,K,E,T,V等
实例:
public <T> T get(T t){
return null;
}
泛型类
实例:
泛型类
public class PersonNew<T> {
private T t;
public PersonNew(T t) {
this.t = t;
}
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
普通类:
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
private Integer age;
}
使用: 使用多参数的父类,增加代码灵活度
public static void main(String[] args) throws Exception {
Person person = new Person();
person.setAge(1);
person.setName("zhangsan");
PersonNew<Person> personNew = new PersonNew<>(person);
PersonNew<String> personNew2 = new PersonNew<>("xiaohong");
}
泛型方法
public class PersonNew2<T,V> {
/**
* 普通方法使用类定义的泛型
* */
public T test1(T t,V v){
return null;
}
/**
* 普通方法使用方法定义的泛型
* */
public <k> k test2(T t,V v){
return null;
}
/**
* 静态方法只能使用方法中的泛型,类中的无法使用,因为类中的泛型在类创建的时候才加载,晚于静态方法
* */
public static <K> K test3(){
return null;
}
}
泛型接口
实例:
创建了一个cal接口,方法都是用int指定返回类型
public interface Cal {
int add(int a,int b);
int sub(int a,int b);
int div(int a,int b);
int mul(int a,int b);
}
public class CalGenera implements Cal{
@Override
public int add(int a, int b) {
return 0;
}
@Override
public int sub(int a, int b) {
return 0;
}
@Override
public int div(int a, int b) {
return 0;
}
@Override
public int mul(int a, int b) {
return 0;
}
}
要使用该接口,需要实现其中的方法,但是实现类返回的参数也都是int类型,如果遇到需要double,Integer类型的需要重新定义
这时,可以指定一个泛型接口,不指定具体方法的返回参数和传入的参数,用泛型代替
public interface CalT<T> {
T add(T a,T b);
T sub(T a,T b);
T div(T a,T b);
T mul(T a,T b);
}
我们需要使用该接口,返回double类型只需要实现该接口
public class CalGeneraTDouble implements CalT<Double>{
@Override
public Double add(Double a, Double b) {
return null;
}
@Override
public Double sub(Double a, Double b) {
return null;
}
@Override
public Double div(Double a, Double b) {
return null;
}
@Override
public Double mul(Double a, Double b) {
return null;
}
}
当我们需要返回Integer类型时,不需要重新定义新的接口,只需要使用
CalT传入Integer类型参数
public class CalGeneraTInteger implements CalT<Integer>{
@Override
public Integer add(Integer a, Integer b) {
return null;
}
@Override
public Integer sub(Integer a, Integer b) {
return null;
}
@Override
public Integer div(Integer a, Integer b) {
return null;
}
@Override
public Integer mul(Integer a, Integer b) {
return null;
}
}