泛型 <T>
泛型的本质是为了参数化类型,即在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型。
最开始接触泛型是在集合中:
List list1=new ArrayList();
List<String> list2=new ArrayList<>();
在list2中指定了数据类型,这样在该集合中只允许存放String类型数据。泛型有三种应用方法:泛型接口、泛型类、泛型方法,此处只讨论泛型类和泛型方法
1、泛型类
直接在类名后修饰
public class Example<T> {
}
在实例化这种类的时候,类似List
Example ex=new Example();
Example<String> ex=new Example<>();
泛型类可以指定参数:
public class Example<T extends String> {
}
在这种情况下,实例化一个对象,必须指定与类相同的参数类型,否则实例化会失败
Example<String> ex=new Example<>();
如果一个子类在继承泛型类的时候,有可能发生泛型擦除,即子类并不是泛型类,为了避免这种情况,可以在父类的构造方法上作出改变。因为子类在实例化的时候,首先调用父类的构造方法,如果在父类内只写(含泛型的)有参构造,那么在子类继承时也必须重写构造方法,这样就能避免泛型擦除:
public class Example<T> {
public T t;
public Example(T t){
this.t=t;
}
}
这样子类在继承的时候,会提示无默认构造方法,这样能起到提示的作用。
2、泛型方法
public <T> void method(T t){
}
public <T> Sting method(T t){
return "hello";
}
这是一个泛型方法的表示。泛型方法在访问修饰符和返回值类型之前必须加上泛型
如果在一个泛型类中,方法可以这样写:
public method(T t){
}
但是这种方法并不是泛型方法,这只是普通方法,只不过在参数列表中含有了泛型。
3、泛型的一种使用场景
当某几个方法出现在许多类中,可以将这些方法封装到一个泛型类中,然后由其他类继承,并制定参数类型,减少代码冗余。