//此时集合以Object形式接收任意类型 ArrayList array=new ArrayList(); array.add(1);//整型 array.add(1L);//浮点型 array.add("abc");//字符型 //编译没问题,运行期报错 int i=(Integer)array.get(1);
//以下集合在创建时加入了泛型参数,限制了其中数据类型 ArrayList<Integer> array=new ArrayList<Integer>(); array.add(1); //array.add(1L);编译报错 //array.add("abc");编译报错 //没问题 int i=(Integer)array.get(0);可以看出,我们在集合创建时便以泛型参数的方式为集合中的数据限制了具体类型,所以在我们取数据时便可知道真实的数据类型,不会再出现类型转换错误,保证了类型安全。
public class GenericTest { public static void main(String[] args) throws SecurityException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { /** * 泛型是提供给javac编译器使用的,只要能跳过编译器,则可以向注明数据类型的集合中添加其他类型的数据。 * 该操作可以通过反射实现,反射在运行期。 */ //指明集合数据类型为Integer,无法在编译期间添加Integer以外的类型 List<Integer> all=new ArrayList<Integer>(); //通过反射跳过编译器,向集合中添加String类型数据 all.getClass().getMethod("add", Object.class).invoke(all,"abc"); //此时输出:abc System.out.println(all.get(0));//abc } }
Collection<String> c=new ArrayList();2、原始类型可以引用一个参数化类型的对象,编译报警告,如下代码所示:
Collection c=new ArrayList<String>();3、参数化类型不考虑类型参数的继承关系
<pre name="code" class="html">Collection<String> c=new ArrayList<String>();//正确 Collection<Object> c=new ArrayList<String>();//错误 Collection<String> c=new ArrayList<Object>();//错误 //但是以下代码却是正确的 Collection c=new ArrayList<String>(); Collection<Object> c1=c; //这是因为c此时是一个原始类型,而参数化的类型可以接收原始类型,千万不要进行替换操作
Vector<Integer>[] vector=new Vector<Integer>[];
/** * 泛型通配符?使用,接收具有任意参数类型的集合 * 使用通配符,不能对集合进行具体类型的操作,如add(E e) * 只能使用与类型无关的方法,如size(); * @param collection */ public void printCollection(Collection<?> collection){ for(Object obj:collection){ System.out.println(obj.toString()); } }
</pre><pre name="code" class="html"><pre name="code" class="html"><pre name="code" class="html" style="font-size:18px;">Collection<? extends Number> c =new ArrayList<Integer>();2、限定通配符的下边界(限定通配符总是包括自己)
Collection<? super Integer> c =new ArrayList<Number>();
/** * 自定义泛型方法 * <T>:声明自定义泛型 * T:返回值 */ public static <T> T add(T x,T y){ return null; }
<span style="font-size:18px;"> //调用自定义泛型方法 add(3, 5); add(3.5, 5); Number result=add(3.5, 6);</span>使用泛型方法时,不必指明参数类型,编译器会自己找出具体的类型。泛型方法除了定义不同,调用就像普通方法一样。
/** * 泛型用于与异常 * 1、T必须是Exception的子类 * 2、catch参数中不能使用该方式:T e */ public static <T extends Exception> void sayHello() throws T{ try { // } catch (Exception e) {//catch参数中不能使用该方式:T e throw (T)e;//可以将异常包装为T抛出 } }
原文地址:http://blog.csdn.net/u012454773/article/details/45741675