• 简单泛型


    使用泛型可以处理多种类型的数据,增加了代码的灵活性。同时,数据类型的确定被推迟到编译阶段,因此编译阶段就可以完成检查,提前发现错误。本文通过例子来说明泛型的使用。

    泛型简单使用

    元组

    元组:将一组对象打包放在了单一对象中,有点像java bean, 使用泛型可以很容易的构造多元元组出来。

    二元组

    public class TwoTuple<A,B> {
    	public final A a;
    	public final B b;
    
    	public TwoTuple(A a, B b) {
    		this.a = a;
    		this.b = b;
    	}
    }
    

    三元组

    public class ThreeTuple<A, B, C> extends TwoTuple<A, B>{
    	public final C c;
    	public ThreeTuple<A a, B b, C c) {
    		super(a, b);
    		this.c = c
    	}
    }
    
    创建一个栈
    public class LinkedStack<T> {	
    	private Node<T> head;
     	class Node<T>{
          	T element;
          	Node<T> next;
      	}
    
    	public void push(T t) {
    		Node<T> node = new Node<>();
    		node.element = t;
    		node.next = head;
    		head = node;
    	}
    
    	public T pop() {
    		if (head != null) {
    			Node<T> node = head;
    			head = node.next;
    			return node.element;
    		} else
    			return null;
    	}
    
    	public static void main(String[] args) {
    		LinkedStack<String> stack = new LinkedStack<String>();
    		stack.push("aa");
    		stack.push("bbb");
    		System.out.println(stack.pop());
    	}
    }
    

    类型推断

    //正常写法
    Map<String, String> map = new HashMap<String, String>();
    
    //类型推断
    Map<String, String> map = new HashMap<>();
    

    类型推断只对赋值操作有校,编译器会自动推断出容器中存储的具体类型。

    泛型擦除

    擦除例子
    public static void main(String[] args) {
        Class c1 = new ArrayList<Integer>().getClass();
        Class c2 =  new ArrayList<String>().getClass();
        System.out.println(c1 == c2);
    }
    

    上面的代码输出结果为true, ArrayList< Integer >ArrayList< String>会被认为是同一种类型。这看起来很奇怪,如果是同一种类型,那么其行为是一致,但事实上我们不能把一个字符串放入ArrayList< Integer >中。这是因为在使用泛型时,任何具体类型信息都会被擦除,你唯一知道的是你在使用一个对象。因此List<Stirng>List<String>在运行时事实上都是原生类型List。

    泛型的擦除是将具体类型信息擦除成原始类型信息,如何实现这一操作请参考连接

    擦除补偿

    由于擦除将类型信息抹掉了,但在实际开发中又需要根据类型进行不同操作,如下所示:

    public class Erased<T> {
    	private final int SIZE = 100;
    	public static void f(Object arg) {
    		if (arg instanceof T) {}             // Compile Error
    		T var = new T();                     // Compile Error
             T[] array = new T[SIZE];             // Compile Error
             T[] array2 = (T) new Oject[SIZE];    // Unchecked warning
    	}
    }
    

    由于擦除,我们获取不同T的任何信息,因此也不能基于T进行相关的类型操作了。那怎么做呢,可以使用Class对象进行处理。

    public class Erased<T> {
        private final int SIZE = 100;
        private final Class<T> kind;
    
        public Erased(Class<T> kind) {
            this.kind = kind;
        }
    
        public void f(Object arg) {
            System.out.println(kind.isInstance(arg));
    
            try {
                T var = kind.newInstance();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }
    
  • 相关阅读:
    英文哲理短句
    经历的一次诈骗
    英文哲理短句
    反思对待新人的方式
    Java 开源报表制作
    现在开始写字
    关于Visual C++ 6.0的调试技巧和经验总结
    一步一步教你实现CTreeCtrl 自绘
    VC中动态加载ODBC解决方法
    VC++程序编译链接的原理与过程
  • 原文地址:https://www.cnblogs.com/xidongyu/p/7542411.html
Copyright © 2020-2023  润新知