程序示例说明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); 
        } 
    } 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值