3.泛型类型范围限定

泛型提供通用方法

/**
* clazz对象创建一个新的实例对象并返回
*
* @param clazz class对象
* @return
* @throws IllegalAccessException
*/
public static <T> T test(Class<T> clazz) throws InstantiationException, IllegalAccessException {
    System.out.println(clazz.getName());
    return clazz.newInstance();
}

指定泛型类型的范围,使用extends或super

extends: 继承限定T的范围上限
super: 限定T范围下限
<T extends User3>限定T要继承User3类或实现User3接口
<T super User3 >限定TUser3的超类
<T extends UserTest1 & User5>限定T要继承UserTest1类或实现UserTest1接口,并且要实现User5接口

<T extends User3>的方法
限制效果:T必须继承User3,否则在运行时会报类型转化异常

extends继承demo

@Data
class UserTest1 {
}
/**
* 规定泛型T的范围是继承User3
*
* @param list TODO
* @return
* @throws
*/
public static <T extends User3> void test5(List<T> list) {
    for (T t : list) {
        System.out.println(t);
    }
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
    List objects1 = Lists.newArrayList();
    UserTest1 userTest1 = new UserTest1();
    objects1.add(userTest1);
    GenericTopic.test5(objects1);
}

test5泛型方法,并指定泛型的范围是继承User3,但是UserTest1并没有继承User3,在遍历list时,就会报类型转化异常。如下异常

Exception in thread "main" java.lang.ClassCastException: com.enterprise.article.base.generic.UserTest1 cannot be cast to com.enterprise.article.base.generic.User3
	at com.enterprise.article.base.generic.GenericTopic.test5(GenericTopic.java:70)
	at com.enterprise.article.base.generic.UseGeneric.main(GenericTopic.java:164)

泛型多继承

<T extends UserTest1 & User5>的用法

限制效果:

  1. T必须继承UserTest1,否则在运行时会报类型转化异常
  2. 在执行User5接口中存在的方法时,T必须实现User5定义的该方法,否则在运行时会报类型转化异常
/**
* 规定泛型T的范围是继承User3并实现User4
*
* @param list TODO
* @return
* @throws
*/
public static <T extends UserTest1 & User5> T test6(List<T> list) {
    for (T t : list) {
        t.user5Method();
        t.user1Method();
    }
    return list.get(0);
}
@Data
class UserTest1 {
}
interface User5 {
    Long user5Id = 123L;
    Long userId = null;

    void user5Method();
}
@Data
class UserTest2 extends UserTest1 {
    public void user5Method() {
        System.out.println("UserTest2 a方法");
    }
}

Test:

public static void main(String[] args) throws InstantiationException, IllegalAccessException {
    List objects1 = Lists.newArrayList();
    UserTest2 userTest2 = new UserTest2();
    objects1.add(userTest2);
    GenericTopic.test6(objects1);
}

在UserTest2不实现User5接口的情况下,执行t.user5Method()会报如下异常。

Exception in thread "main" java.lang.ClassCastException: com.enterprise.article.base.generic.UserTest2 cannot be cast to com.enterprise.article.base.generic.User5

原因是在执行User5接口中存在的方法时,如user5Method方法,T类必须实现并覆盖User5的该方法。才能执行该方法。

以下场景能够运行成功:

  1. 该方法没有在User5接口中定义,并且该方法是UserTest1的方法。
  2. 不执行User5中的方法,相当于,去除了实现User5的限制

版权声明:本文为u010106375原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。