美文网首页
Java语法糖之泛型

Java语法糖之泛型

作者: sunpy | 来源:发表于2018-10-06 12:48 被阅读11次

    为什么需要泛型

    泛型本质就是 “ 参数化类型 ”,泛型为我们在编译时指明了参数的类型。如果我们不使用泛型,那么不知道参数的类型,我们的做法可能就是强制类型转换,这样很容易会出现ClassCastException强制类型转换错误。但是使用了泛型,我们就可以在编译期捕获到类型转换错误,而不用等到运行期接受异常。如果我们不使用泛型,最终的结果就是到处都是Object和强制类型转换,代码的可阅读性极差。

    泛型的擦除

    在Java语言中泛型的实现策略是采用类型擦除,而这种方式成为伪泛型。

    public class CaseTest {
    
        public static void main(String[] args) {
            List<String> strList = new ArrayList<String>();
            List<Integer> iList = new ArrayList<Integer>();
        }
    }
    

    CaseTest.class反编译后:


    反编译CaseTest.class.jpg

    说明:
    可以发现java代码经过编译后的class文件,泛型类型都变回了原生类型。可以得到的结果就是java代码在编译期会将泛型代码内部的类型擦除;同时我们在泛型代码内部,也就无法获得任何有关泛型参数类型的信息了。

    泛型擦除中方法重载问题

    2.jpg

    说明:可以看出泛型在编译期会变回List<E>这样,重载的方法产生冲突了。所以编译期是不会通过的。。

    泛型中协变

    协变实际就是小范围的类型代替大范围的类型。我们可以使用<? extends T>实现了泛型的协变。


    集合框架协变.jpg

    可以看出java本身这种隐式的协变是不支持的,需要我们显式的指出这种小范围代替大范围的协变。


    <? extends T>例子.jpg

    泛型中逆变

    逆变实际上就是大范围类型代替小范围类型。我们可以使用<? super T>实现了泛型的逆变。


    集合框架逆变.jpg

    可以看出java本身对这种隐式逆变是不支持的,我们可以显式地使用逆变。


    <? super T>例子.jpg

    基类劫持接口

    public interface MyInterface<T> {
        public void print(T t);
    }
    
    7.jpg

    说明:可以发现编译不通过,会提示接口不可以实现超过1个的不同参数。

    相关文章

      网友评论

          本文标题:Java语法糖之泛型

          本文链接:https://www.haomeiwen.com/subject/nfqcaftx.html