泛型种类
1)泛型类
public class 类名 <泛型类型1,...> {}
示例:
//泛型类
public class GenericClass<T> {
private T value;
public GenericClass(T value) {
this.value = value;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
//测试类
GenericClass<String> name = new GenericClass<>("哈哈");
System.out.println(name.getValue());
GenericClass<Integer> number = new GenericClass<>(123);
System.out.println(number.getValue());
2)泛型接口
public interface 接口名 <泛型类型1,...> {}
示例:
public interface GenericInterface<T> {
void show(T value);
}
public class StringShowImpl implements GenericInterface<String> {
@Override
public void show(String value) {
System.out.println(value);
}
}
public class NumberShowImpl implements GenericInterface<Integer> {
@Override
public void show(Integer value) {
System.out.println(value);
}
}
3)泛型方法
public <泛型类型> 返回类型 方法名(泛型类型 变量名) {}
注意要点: 方法声明中定义的形参只能在该方法里使用,而接口、类声明中定义的类型形参则可以在整个接口、类中使用。当调用fun()方法时,根据传入的实际对象,编译器就会判断出类型形参T所代表的实际类型。
public <T> T genercMethod(T t){
System.out.println(t.getClass());
System.out.println(t);
return t;
}
泛型通配符
- E:Element (在集合中使用,因为集合中存放的是元素)
- T:Type(Java 类)
- K:Key(键)
- V:Value(值)
- N:Number(数值类型)
- ?:无界通配符,表示不确定的java类型
无界通配符
”?” 用于方法形参 比如我们在 无界通配符 “?” 的代码示例,即使不在泛型类中,”?” 也可以作为方法形参,定义方法返回值等,但是我们不能对 “?” 进行单独定义、操作
示例1:
private List<?> list;
private ? data;//报错
public class OrderRequest<?> {}//报错
public void test(? item){}//报错
示例2:
static int countLegs (List<? extends Animal > animals ) {
int retVal = 0;
for ( Animal animal : animals )
{
retVal += animal.countLegs();
}
return retVal;
}
static int countLegs1 (List< Animal > animals ){
int retVal = 0;
for ( Animal animal : animals )
{
retVal += animal.countLegs();
}
return retVal;
}
public static void main(String[] args) {
List<Dog> dogs = new ArrayList<>();
// 不会报错
countLegs( dogs );
// 报错
countLegs1(dogs);
}
注意:
1)类型参数可以多重限定而通配符不行 2)通配符可以使用超类限定而类型参数不行
类型参数 T 只具有 一种 类型限定方式:
T extends A
但是通配符 ? 可以进行 两种限定:
? extends A
? super A
泛型上下边界
// 1:表示类型参数可以是任何类型
public class Apple<?>{}
// 2:表示类型参数必须是A或者是A的子类
public class Apple<T extends A>{}
// 3: 表示类型参数必须是A或者是A的超类型
public class Apple<T supers A>{}
- 无边界的通配符(Unbounded Wildcards), 就是<?>, 比如List<?>
- 固定上边界的通配符(Upper Bounded Wildcards),采用<? extends E>的形式
- 固定下边界的通配符(Lower Bounded Wildcards),采用<? super E>的形式
泛型擦除
1)普通类型
替换为Object
//普通泛型 public class Caculate<T> { private T num; } //类型擦除后 public class Caculate{ public Caculate(){} private Object num; }
2)有上界情况
替换为上界类型