泛型

泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。Java语言引入泛型的好处是安全简单。
在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。
泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,以提高代码的重用率。

定义泛型类,泛型方法,泛型接口的时候经常会碰见很多不同的通配符T,E,K,V,?等等很多通配符类型,

  • ? 表示不确定的java类型
  • * T (type)* 表示具体的一个java类型
  • K V (key value) 分别代表java键值中的Key Value
  • E (element) 代表Element

下面说说这些通配符类型的区别,大致分为两种:

通配符T,E,K,V

这种通配符表示赋值的都是具体的类型,符号只是一个标记,可以是任意的A,B,C,D…都可以,可以看个例子:

1.泛型类:

public class Parse<T> {

}

这里可以定义多个泛型参数,比如:

public class Parse<K,V> {

}

2.泛型方法

public <T> void print(T t){
    System.out.println(t);
}

public <K,V> void print(K k,V v){

}

public <T> void print(List<T> t){
    System.out.println(t);
}

3.泛型接口

interface Parse<K,V> {
    void parse(K k, V v);
}

4.限定修饰符extends、super

public <T extends Map> void print(T t){
    System.out.println(t);
}

当实例化泛型或调用泛型方法时,必须把T换成具体的类型,如果未指定,默认是Object类型,Object是所有的类的父类。

public static <T> void print(List<T> t){
    System.out.println(t);
}

List<?> list =new ArrayList();
print(list);
List<String> list1 =new ArrayList();
print(list1);
List list2 =new ArrayList();
print(list);

通配符?

泛型中当赋值的类型不确定的时候,我们用通配符(?)代替了。

private List<?> list;

List<? extends Integer> list1;

List<? extends People> peopleList;

private List<? super People> peoples;

public void print(List<?> t){
    System.out.println(t);
}

在Java集合框架中,对于参数值是未知类型的容器类,只能读取其中元素,不能向其中添加元素, 因为,其类型是未知,
所以编译器无法识别添加元素的类型和容器的类型是否兼容,唯一的例外是NULL.

T,Class<T>,Class<?>区别

T是一种具体的类,例如String,List,Map……等等,这些都是属于具体的类,这个比较好理解
* Class是什么呢,Class也是一个类,但Class是存放上面String,List,Map……类信息的一个类*

如何获取到Class类呢,有三种方式:
1. 调用Object类的getClass()方法来得到Class对象,这也是最常见的产生Class对象的方法。
例如:

List list = null;
Class clazz = list.getClass();
**2. 使用Class类的中静态forName()方法获得与字符串对应的Class对象。
**
例如:

Class clazz = Class.forName(“com.github.demo.domain.People”);
3.获取Class类型对象的第三个方法非常简单。如果T是一个Java类型,那么T.class就代表了匹配的类对象。

Class clazz = List.class;
* 那么问题来了?Class类是创建出来了,但是Class<T>和Class<?>适用于什么时候呢???*

使用Class<T>和Class<?>多发生在反射场景下,先看看如果我们不使用泛型,反射创建一个类是什么样的。

People people = (People) Class.forName("com.github.demo.domain.People").newInstance();

看到了么,需要强转,如果反射的类型不是People类,就会报
java.lang.ClassCastException错误。

Class<T>:
public static <T> T getInstance(Class<T> clazz) throws IllegalAccessException, InstantiationException {
    return clazz.newInstance();
}

People people = getInstance(People.class);

Class<?>:
Class<?> class = Class.forName("com.github.demo.domain.People");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值