Java中泛型的详细解析,深入分析泛型的使用方式 (4)

为泛型方法添加上边界,即传入的类型实参必须是指定类型的子类型:

public void showKeyValue1(Generic<? extends Number> obj) { Log.d("泛型测试", "key value is" + obj.getKey()); } Generic<String> generic1 = new Generic<String>("11111"); Generic<Integer> generic2 = new Generic<Integer>(2222); Generic<Float> generic3 = new Generic<Float>(2.4f); Generic<Double> generic4 = new Generic<Double>(2.56); /* * 这一行在编译的时候就会报错,因为String类型并不是Number类型的子类 * * showKeyValue1(generic1); */ showKeyValue2(generic2); showKeyValue3(generic3); showKeyValue4(generic4);

为泛型类添加上边界,即类中泛型必须是指定类型的子类型:

public class Generic<T extends Number> { private T key; public Generic(T key) { this.key = key; } public T getKey() { return key; } } /* * 这一行代码在编译的时候会报错,因为String的类型不是Number的子类 */ Generic<String> generic1 = new Generic<String>("1111");

在泛型方法中添加上下边界限制时,必须在权限声明与返回值之间的< T >上添加上下边界:

/* * 如果使用: * public <T> showKeyName(Generic<T extends Number> container); * 编译器会报错. */ public <T extends Number> T showKeyName(Generic<T> container) { System.out.println("container key:" + container.getKey()); T test = container.getKey(); return test; }

从上面可以看出 : 泛型的上下边界添加,必须与泛型的声明在一起

泛型数组

在Java中,不能创建一个确切的泛型类型的数组

/* * 这个数组创建的方式是不允许的 * List<String>[] ls = new ArrayList<String>[10]; */ // 使用通配符创建泛型数组是可以的 List<?>[] ls = new ArrayList<?>[10]; // 下面的这个方法也是可以的 List<String> ls = new ArrayList[10];

示例:

List<String>[] lsa = new List<String>[10]; //不允许这样定义 Object o = lsa; Object[] oa = (Object) o; List<Integer> li = new ArrayList<Integer>(); li.add(new Integer(3)); oa[1] = li; // 不建议这样使用,但是可以通过运行时检查 String s = lsa[1].get(0); // 运行时报错,类型转换异常

由于JVM的擦除机制,在运行时JVM是不知道泛型信息的:

所有可以给oa[1] 赋值一个ArrayList却不会出现异常

但是在取出数据的时候要做一次类型转换,就会出现ClassCastException

如果可以进行泛型数组的声明,那么上面的这种情况在编译期将不会出现任何警告和错误,只有在运行时才会报错

通过对泛型数组的声明进行限制,对于这样的情况,可以在编译期提示代码有类型安全问题

数组的类型不可以是类型变量,除非是采用通配符的方式: 因为对于通配符的方式,最后取出数据是要做显式的类型转换的

List<?>[] lsa= new List<?>[10]; // 可以这样定义为泛型数组 Object o = lsa; Object[] oa = (Object[]) o; List<Integer> li = new ArrayList<Integer>(); li.add(new Integer(3)); oa[1] = li; // 可以这样赋值 Integer i = (Integer) lsa[1].get(0); // 可以这样取出数据

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzddxj.html