泛型
泛型的类型必须是一个类,它不能是基本数据类型
所谓泛型,就是允许在定义类、属性接口时通过一个标识标识类中的某个属性的类型或者是某个方法的返回值及参数类型。这个类型参数将在使用时(例如,继承或实现这个接口,用这个类型声明变量、创建对象时)确定(即传入实际的类型参数,也称为类型实参)。
JDK1.5之后,Java引入了“参数化类型”的概念,允许我们在创建集合的时候指明集合参数的类型。
JDK1.5之后改写了集合框架中的全部接口和类,为这些接口和类增加了泛型的支持,从而可以在声明集合变量、创建集合对象时传入类型实参。
为什么需要泛型?
①解决元素存储时的安全性问题
②解决获取数据元素时,需要类型强制转换、可能会出现ClassCastException异常的问题。
集合中使用泛型
自定义泛型结构
1. 泛型的声明
interface List<T> 和 class GenTest<K,V> 其中,T,K,V不代表值,而是表示类型。这里使用任意字母都可以。 常用T表示,是Type的缩写。
2. 泛型的实例化
List<String> strList = new ArrayList<String>();
T只能是类,不能用基本数据类型填充,但可以使用包装类填充
把一个集合中的内容限制为一个特定的数据类型,这就是generics背后 的核心思想
使用泛型的主要优点是:能够在编译时而不是在运行时检测错误。
//Order泛型类
public class Order<T> {
private String orderName;
private int orderId;
private T orderT;
public Order(){
}
public T getOrderT() {
return orderT;
}
public void setOrderT(T orderT) {
this.orderT = orderT;
}
@Override
public String toString() {
return "Order{" +
"orderName='" + orderName + '\'' +
", orderId=" + orderId +
", orderT=" + orderT +
'}';
}
}
public class GenericTest {
public static void main(String[] args) {
Order order = new Order();
order.setOrderT(123);
order.setOrderT("啦啦啦");
//如果定义了泛型类,实例化没有指明类的泛型,则认为此泛型类型为Object类型
//要求:如果大家定义了泛型类,则在实例化的时候就要指明泛型的类型
Order<String> order1 = new Order<>();//后面的<>可以不写内容是因为在JDK1.7之后引入了一个小功能:类型推断,根据前面的类型推断后面的类型
order1.setOrderT("我肥来了呀");
order1.setOrderT("是吗?");
//子类继承泛型类
//①该子类不是泛型类
//public class SubOrder extends Order<Integer>{}
SubOrder subOrder = new SubOrder();
subOrder.setOrderT(12345);
subOrder.setOrderT(888);
//②该子类也是泛型类
//public class SubOrder1<T> extends Order<T>{ }
SubOrder1<String> subOrder1 = new SubOrder1<String>();
subOrder1.setOrderT("我只能是String类型");
subOrder1.setOrderT("是的呢");
}
}
注意点:
1. 静态方法中不能使用类的泛型,因为类的泛型是在实例化之后才创建,而静态方法是在实例化之前就被创建了的。一个存在的东西不能调用一个不存在的东西。
2. 泛型方法,可以声明为静态的。原因:泛型参数是在调用的时候确定的,并非是在实例化类的时候确定。
3. 异常类不能是泛型的
泛型方法
泛型方法只是针对于方法本身来讲,与方法所在的类或接口是否为泛型类、泛型接口没有关联。
不是说方法中使用了类的泛型就是泛型方法,泛型方法是在方法中出现了泛型的结构,泛型参数与类的泛型没有任何关系,换句话说,泛型方法所处的类是不是泛型类都没有关系。
注意:泛型方法,可以声明为静态的。原因:泛型参数是在调用的时候确定的,并非是在实例化类的时候确定。
举个栗子:
`` java
//泛型方法
public <E> List<E> copyFromArrayToList(E[] arr){
ArrayList<E> list = new ArrayList<>();
for(E e:arr){
list.add(e);
}
return list;
}
//调用该方法
@test
public void test4(){
Order<String> order = new Order<>();
Integer[] arr = new Integer[]{1,2,3,4};
//泛型方法再调用是,指明泛型参数的类型
List<Integer> list = order.copyFormArrayList(arr);
System.out.println(list);
}
泛型在继承方面的体现
虽然类A是类B的父类,但是G<A>和G<B>二者不具备子父类的关系,二者是并列关系。
#通配符的使用
通配符:?
类A是类B的父类,G<A>和G<B>是没有关系的,二者共同的父类是:G<?>
举个列子
public void test(){
List<Object> list1 = null;
List<String> list1 = null;
List<?> list = null;
list = list1;
list = list2;
print(list1);
print(list2);
}
public void print(List<?> list){
Iterator<?> iterator = list.iterator();
while(iterator.hasnext){
Object obj = iterator.next();
System.out.println(obj);
}
}
声明
这些知识点是本人在学习的时候所做笔记,如有侵权,请联系