- 泛型的目的
在写程序的过程中,往往一个类的同一参数可能有多种类型。为了实现这个目标。
我么可以在调用的时候由开发者自己决定参数的类型。
这种方法可以解决向下转型过程中可能出错的问题。
例如
public class Test {
private Object name;
public Object getName() {
return name;
}
public void setName(Object name) {
this.name = name;
}
}
在调用时
Test test = new Test();
test.setName("sdfdsfdsf");
int name = (int) test.getName();
这样就会出错。
像上转型 例如 从 String 转为 Object 比较安全。
像下转型 例如 从 Object 转为 String 则很有可能带来风险。
2.引入泛型机制
public class Static<T,F> {
private T name;
private F judge;
public T getName() {
return name;
}
public void setName(T name) {
this.name = name;
}
public F getJudge() {
return judge;
}
public void setJudge(F judge) {
this.judge = judge;
}
}
public class test {
public static void main(String [] args) {
Static<String,Boolean> test = new Static<>();
test.setJudge(false);
test.setName("test");
System.out.println(test.getJudge()+ "," + test.getName());
}
}
这样就能自定义参数的类型了。
3.泛型的类型只能是引用类型 类和接口,不能是基本数据类型。
4.通配符
但是用了泛型会有一个新的问题
例如 使用上例中的类举例。
Static<String,Boolean> test = new Static<>();
test.setJudge(false);
test.setName("test");
testFanXing(test);
下面是一个方法
public static void testFanXing(Static<String,Boolean> test) {
System.out.println(test.getName);
}
但是当 test的泛型new的时候和方法不一样时,就会报错了。
为了避免这种错误 需要给方法一个通配符,让其能接受所有类型的泛型参数。
可以这样写
public static void testFanXing(Static<?> test) {
System.out.println(test.getName);
}
这样就可以解决这个问题了
除此之外还衍生出 泛型上限和泛型下限例如:
<? extends Number> 泛型上限 泛型必须是Number的子类
和 <? super String> 泛型上限 泛型必须是String的父类 如 Object
一般 上限在 类中定义。下限在方法中定义,下面是泛型上限例子
public class Static<T extends Number ,F> { //泛型上限
private T name;
private F judge;
public T getName() {
return name;
}
public void setName(T name) {
this.name = name;
}
public F getJudge() {
return judge;
}
public void setJudge(F judge) {
this.judge = judge;
}
}
public static void testFanXing(Static<? extends Number> test) {
System.out.println(test.getName);
}
下面是泛型下限
泛型下限只能在方法中写:
public static void testFanXing(Static<? super String> test) {
System.out.println(test.getName);
}