12-泛型

nobility 发布于 2021-03-21 1782 次阅读


泛型

泛型通配符

为泛型对象作为参数数据类型的方法或类限制泛型的类型范围,类中使用具体的字母<T>,方法中使用问号表示<?>,使得数据类型参数化

若方法不为参数是泛型对象设置通配符,则默认通配符是Object,该对象内容是允许修改成其他数据类型的

设置泛型通配符的方法可以接受所有泛型类的对象,但是对象内容是不允许修改的,只能获取

  • <?>:接受所有类为泛型的对象,可用于方法和类上,类上用具体变量表示,如<T>
  • <? extends 类名>:接受该指定类以及子类作为泛型的对象,可用于方法和类上
  • <? super 类名>:接受该指定类以及父类作为泛型的对象,只能用于方法上

泛型类

定义

public class Test<T> {
  //泛型标记采用类名后尖括号包裹形式,多个泛型使用逗号分隔<T,E>,使用时也是一样
  private T t;	//数据类型参数化

  public T getT() {	//数据类型参数化
    return t;
  }

  public void setT(T t) {	//数据类型参数化
    this.t = t;
  }

  public static void main(String[] args) {
    Main<Integer> main = new Main<>();	//设置Integer类型
    //main.setT("1");	//报错,定义泛型类型后,在编译时就会检测出数据类型不匹配错误
    int value = test.getT();	//设置具体类型后,就不必强制转型,避免了类型转换异常
    
    Test test = new Test();	//没有设置泛型类型
    test.setT(1);
    int value = (Integer)test.getT();	//默认是是Object类型,需要向下强制转换
  }
}

使用

  1. 在定义泛型类型时只允许设置类,不允许设置基本数据类型,所以基本数据类型用包装类
  2. jdk1.7之前使用泛型类只能Test<Integer> test = new Test<Integer>(),jdk1.7后泛型可简化定义将后面的尖括号省略Test<Integer> test = new Test<>();,在括号前面加加括号
  3. 若使用泛型类没有设置泛型类型,则泛型类型默认是是Object类型

泛型接口

实现类未实现泛型

interface Test<T> {
  public void fun(T t);
}
class TestImpl implements Test{
  @Override
  public void fun(Object o) {
    //无法使用泛型,重写带泛型的方法只能用Object类型
    System.out.println(o);
  }
}

实现类实现泛型

interface Test<T> {
  public void fun(T t);
}
class TestImpl<T> implements Test<T>{
  //要保证前后泛型变量一致
  @Override
  public void fun(T t) {
    //实现类重写带泛型方法可以使用泛型
    System.out.println(t);
  }
  public static void main(String[] args) {
    TestImpl<String> testImpl = new TestImpl<>(); //实现类也会拥有泛型
    //Test<String> testImpl = new TestImpl<>(); //自动向上转型
    testImpl.fun("1");
  }
}

实现类固定泛型

interface Test<T> {
  public void fun(T t);
}
class TestImpl implements Test<String>{	//将接口泛型具体化
  @Override
  public void fun(String t) {	//带泛型的方法直接使用具体化的数据类型即可
    System.out.println(t);
  }
  public static void main(String[] args) {
    TestImpl testImpl= new TestImpl();	//实现类不需要在指定泛型
    testImpl.fun("1");
    //Test<String> test= new TestImpl();
    //Test<Integer> test= new TestImpl();	报错
    //多态向上转型时需要为接口指定与实现类的泛型,若不一致会报错
    
    //Test test= new TestImpl();	//若不指定接口泛型
    //test.fun(123);
    //这种情况在自动拆箱时,会抛出类型转换异常,Integer无法转换为String
  }
}

泛型方法

在没有定义泛型的类中定义泛型方法,泛型定义必须在返回值类型之前,修饰符之后定义

public class Test {
  public static <T> T fun(T t){	//在修饰符和返回类型之间定义泛型
    System.out.println(t);
    return t;	//返回值类型可以是泛型
  }
  public static void main(String[] args) {
    String a = Test.fun("123");
    //Integer a = Test.fun("123");	//报错,该方法要求参数和返回类型一致
    System.out.println(a);
    Integer b = Test.fun(123);	//只要是返回值和参数类型一致即可
    System.out.println(b);
  }
}
此作者没有提供个人介绍
最后更新于 2021-03-21