程序示例说明Java泛型到底是什么

Java泛型到底什么,在看《数据结构与算法分析》一书时我不禁问自己。其书中介绍甚为抽象,本人就想试着用程序实验一下java泛型。参考了小顾问@cnblogs的关于java泛型的博文。本人的理解Java泛型其实就是参数类型的类型。

泛型基础

/** * * @author wqh * 泛型基础 */
public class GenericDemo1 {
    /** * 未使用泛型 */
    public static void test0() {
        Map m = new HashMap();
        m.put("key", "yes");
        String s = (String) m.get("key");// 类型强制转换
    }

    /** * 未使用泛型 * 没进行型强制转换,无法通过编译 */
    public static void test1() {
        Map m = new HashMap();
        m.put("key", "yes");
        //String s = m.get("key");// 无类型强制转换,编译无法通过
    }

    /** * 未使用泛型 * map中保存了Integer类型的对象,运行时抛出 ClassCastException */
    public static void test2() {
        Map m = new HashMap();
        m.put("key", new Integer(3));// 值可为任意对象,编译可以通过
        String s = (String) m.get("key");// 类型强制转换
    }

    /** * 使用泛型 * 注意Map的声明,声明时就指定了变量的类型, * Map<String, String>类型的对象,Map.put()方法参数类型必须为String, * Map.get()方法 将会得到 String 类型. * map中保存了Integer类型的对象,编译无法通过 */
    public static void test3() {
        Map<String, String> m = new HashMap<String, String>();// 使用泛型
        // m.put("key", new Integer(3));//编译无法通过
        String s = m.get("key");// 不需要类型强制转换
    }

    /** * 使用泛型 * */
    public static void test4() {
        Map<String, String> m = new HashMap<String, String>();// 使用泛型
        m.put("key", "yes");// 编译通过
        String s = m.get("key");// 不需要类型强制转换
    }

    public static void main(String[] args) {
        test2();//抛出 ClassCastException

    }
    /** * 以上代码可以看出,如果使用泛型 * 1.保存在Map中值的类型错误时不能编译通过,类型安全 * 2.在获取值时不需要进行强制类型转换,提高可靠性并加快开发速度 * 结论:泛型消除代码中的强制类型转换,并且进行类型检查!!! */
}

泛型通配符

/** * * @author wqh * 泛型通配符 */
public class GenericDemo2 {

    /** * 数组是协变的,意思是在可以需要用numberArray的地方使用intArray */
    private void test0() {
        Integer[] intArray = new Integer[10]; 
        Number[] numberArray = intArray;
    }
    /** * 泛型不是协变的,不可以在需要listObject的地方使用listString * String是Object的子类,但是List<String>和List<Object>却没有这种继承关系 */
    public static void test1(){
        List<Object> listObject = new ArrayList<Object>();
        List<String> listString = new ArrayList<String>();


    }
    /** * 如果泛型协变的,就会违背泛型应该提供的类型安全 * Integer和Float不是同一种类型 */
    public void test2() {
        List<Integer> intList = new ArrayList<Integer>();
        List<Number> numberList = intList; // 编译不通过,无效代码
        numberList.add(new Float(3.1415));//违背泛型应该提供的类型安全
    }
    /** * printList1方法的参数类型只能是List<Object>,调用时传入List<Integer>编译不能通过 * */
    public void printList1(List<Object> l) { 
        for (Object o : l){
            System.out.println(o); 
        } 
    }

    /** * 为了灵活使用泛型,引入类型通配符。 * printList2方法的参数类型可以是 * List<Object>、List<Integer> 或 List<List<List<Object>>> * */

    public void printList2(List<?> l) { 
        for (Object o : l) {
             System.out.println(o); 
        } 
    }
    /** * 类型通配符?的作用 * 编译器不知道 List的类型参数的值,但是编译器可以推理, * 它推断未知的类型参数必须扩展 Object * 1.但是编译器不能对 List的类型参数作出足够严密的推理, * 以确定将 Integer 传递给 List.add() 是类型安全的 * 所以lu.add的方法编译不通过 * 2.不依赖于编译器必须知道关于lu的类型参数的方法 * 则是可以编译通过的,例如lu.clear() */
    public void test4() {
        List<Integer> li = new ArrayList<Integer>();
        li.add(new Integer(3));
        List<?> lu = li;
        System.out.println(lu.get(0));
        lu.add(new Integer(4)); // 编译无法通过
        lu.clear();
    }


}

泛型方法

/** * * @author wqh * 泛型方法 * */
public class GenericDemo3 {
    /** * 泛型方法是为了想要在该方法的多个参数之间宣称一个类型约束 * ifThenElse方法不用显式地告诉编译器T是什么值, * 编译器可以使用类型推理来推断出 */
    public <T> T ifThenElse(boolean b, T first, T second) {
        return b ? first : second;
    }
    /** * 调用方法ifThenElse */
    private void test0() {
        String s1 = 
                ifThenElse(true, "a", "b");
        //编译通过:"a","b"是String类型,类型相同

        Integer i = 
                ifThenElse(false, new Integer(1), new Integer(2));
        //编译通过:new Integer(1), new Integer(2)
        //是Integer类型

        String s2 = 
                ifThenElse(false, "pi", new Float(3.14));
        //编译不通过:"pi", new Float(3.14)类型不同

    }
    /** * 在还没有完全指定类型参数时,需要对类型参数指定附加的约束 * 类型参数 V 被判断为由 Number限制 。 * 在没有类型限制时,假设类型参数由 Object限制 */
    public class Matrix<V extends Number> { }
    /** * 允许创建Matrix<Number>、Matrix<Integer>类型的对象, * 但是不允许创建Matrix<String>的对象 */
    private void test1() {
         new Matrix<Number>();//编译通过
         new Matrix<Integer>();//编译通过
         new Matrix<String>();//编译不通过

    }
}

泛型高级

/** * * @author wqh * 泛型高级 * 此部分内容本人理解也不是很好,不是很详尽,Selector的东西还需要研究 */
public class GenericDemo4 {
    /** * Java类库中的泛型 * 该定义组合了通配符类型参数和有限制类型参数, * 允许您将 Collection<Integer> 的内容添加到 Collection<Number>。 */
    interface Collection<V> {
        boolean addAll(Collection<? extends V> paramCollection);
     }

    /** * 二元 max() 方法的实现 * 使用泛型方法和有限制类型参数 */

    public static <T extends Comparable<T>> T max(T t1, T t2) {
        if (t1.compareTo(t2) > 0)
            return t1;
        else
            return t2;
    }
    /** * 让 T.class是 Class<T> 类型的好处是,通过类型推理, * 可以提高使用反射的代码的类型安全 * 还不需要将 T.class.newInstance()强制类型转换为T * 此方法实现从数据库检索一组对象,并返回 JavaBeans 对象的一个集合 * @throws IllegalAccessException * @throws InstantiationException */
    public static <T> List<T> getRecords(Class<T> c, Selector s) throws 
    InstantiationException, IllegalAccessException {
        // Use Selector to select rows
        List<T> list = new ArrayList<T>();
        for (/* iterate over results */;;) {
            T row = c.newInstance();
            // use reflection to set fields from result
            list.add(row); 
        }
    }
    /** * 用 Class<T> 替换 T[] * Collection 接口还没有改变为使用该技术, * 因为这会破坏许多现有的集合实现 * 但是如果使用泛型从新构建 Collection, * 则当然会使用该方言来指定它想要返回值是哪种类型。 * 调用:Integer[] integer = new GenericDemo4().toArray(Integer.class); * */
    public   <T> T[] toArray(Class<T> returnType) {
        //未实现
        return null;
    }


}

一个简单的泛型类

/** * * @author 小顾问@cnblogs * * @param <V> * 一个简单的泛型类,类似于 List,充当一个容器 * 泛型类最常见的用例是容器类(比如集合框架) * 或者值持有者类(比如 WeakReference 或 ThreadLocal) */
public class SimpleGenericList<V> {
    private V[] array;
    private int size;

    public SimpleGenericList(int capacity) {
        array = (V[]) new Object[capacity];
        //List构造函数的一种可能的实现
    }

    public void add(V value) {
        if (size == array.length)
            throw new IndexOutOfBoundsException(Integer.toString(size));
        else if (value == null)
            throw new NullPointerException();
        array[size++] = value;
    }

    public void remove(V value) {
        int removalCount = 0;
        for (int i = 0; i < size; i++) {
            if (array[i].equals(value))
                ++removalCount;
            else if (removalCount > 0) {
                array[i - removalCount] = array[i];
                array[i] = null;
            }
        }
        size -= removalCount;
    }

    public int size() {
        return size;
    }

    public V get(int i) {
        if (i >= size)
            throw new IndexOutOfBoundsException(Integer.toString(i));
        return array[i];
    }
}
/** * * @author 小顾问@cnblogs * 作为从原始集合类型迁移到泛型集合类型的帮助, * 集合框架添加了一些新的集合包装器, * 以便为一些类型安全 bug 提供早期警告 */ public class Collections { public static <E> Collection<E> checkedCollection(Collection<E> c, Class<E> type ) { return new CheckedCollection<E>(c, type); } //省略了部分Collection<E>中定义的接口的实现 private static class CheckedCollection<E> implements Collection<E> { private final Collection<E> c; private final Class<E> type; CheckedCollection(Collection<E> c, Class<E> type) { this.c = c; this.type = type; } public boolean add(E o) { if (!type.isInstance(o)) throw new ClassCastException(); else return c.add(o); } } } 

你可能感兴趣的:(java,泛型,基础,Class)