• EffectiveJava——请不要在代码中使用原生态类型


      先看一个栗子,看看能不能找出来里面的错误:

    /**
     * 请不要在新代码中使用原生态类型
     * @author weishiyao
     *
     */
    public class Test {
    	
    	public static void main(String[] args) {
    		List<String> strings = new ArrayList<>();
    		unsafeAdd(strings, new Integer(42));
    		String string = strings.get(0);
    		System.out.println(string);
    	}
    	
    	private static void unsafeAdd(List list, Object object) {
    		list.add(object);
    	}
    }
    

      运行一下,看一下报错结果:

    Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
    	at com.weishiyao.effectiveJava.entry23.Test.main(Test.java:16)
    

      对的,是一个ClassCastException,这是一个编译器声称的转换,因此一般会保证成功,但是我嘛在这个栗子中忽略了一条编译器的警告,就会为此而付出代价。

      但是,如果用unsafeAdd(List<Object> list, Object object)代替原生的List类型,我们的IDE会直接报错。

      在不确定或者不在乎集合中元素类型的情况下,你也许会使用原生态的类型。例如,假设想要编写一个方法,它有两个集合(set),并从中返回他们公有的元素的数量。如果不熟悉范型的话,可以参考以下方式来编写这种方法:

    	static int numElementsInCommen(Set s1, Set s2) {
    		int result = 0;
    		for (Object object : s1) {
    			if (s2.contains(object)) {
    				result++;
    			}
    		}
    		return result;
    	}
    

      这个方法倒是可行,但是它使用了原生态类型,这是很危险的。从java1.5发行版本开始,java就提供了一种安全的替代方法,称作无限制的通配符类型,如果要使用范型,但是确定或者不关心实际的参数类型,就可以用一个问号代替。例如范型Set<E>的无限制通配符类型为Set<?>。这是最普通的参数化Set类型,可以持有任何集合。

      在无限制通配类型Set<?>和原生态类型Set之间有什么区别呢?这个问号真正起到作用了么?这一点不需要赘述,但通配符类型是安全的,原生态类型则不安全。可以将任何元素放入使用原生态类型的集合中,因此很容易破坏该集合类型的约束条件;但不能将任何元素(除了null)放到Collection<?>中。

      不要在新代码中使用原生态类型,这条规则有两个小小的例外,两者都源于“范型信息可以在运行时被擦除”这一事实。在类文字中必须使用原生形态规范不允许使用参数化类型。换句话说,List.class,String[].class和int.class都是合法的。但是List<String>.class和List<?>则不合法。

      这条规则第二个例外与instanceof操作符有关。由于范型信息可以在运行时被擦除,一次在参数化类型而非无限制通配符上使用instanceof操作符时非法的。用无限制通配符类型代替原生态类型,对instanceof操作符的行为不回产生任何影响。在这种情况下,尖括号<>和问号?就显得多余了。下面是利用范型来使用instanceof操作符的首选方法:

    				if (object instanceof Set) {	// Raw type
    					Set<?> m = (Set<?>) object;	// Wildcard type
    				}
    

      注意,一旦确定这个object是个Set,就必须将他转换成通配符类型Set<?>,而不是原生类型,这个是受检的,否则的话我们的IDE还是会报错的。

  • 相关阅读:
    sudo 之后 unable to resolve host的问题解决办法
    Linux 查找具体的文件名称
    linux 访问远程务器代码
    spark 安装配置
    R基本介绍
    BIEE多层表头报表的制作方法
    支付宝新漏洞引发恐慌,那如何关闭小额免密支付呢
    大家注意了,支付宝被曝重大安全漏洞,回应称正在跟进排查
    2017年5个不应该被忽视的机器学习项目
    婚前最后一次加班
  • 原文地址:https://www.cnblogs.com/babycomeon/p/5598697.html
Copyright © 2020-2023  润新知