【Java基础】泛型与泛型擦除

  • 泛型( 以下代码仅可在jdk1.6时可编译通过,其他版本仍可以拒绝编译3.2

  • 1.什么是泛型?

    • 它是JDK1.5引进的新特性。
    • 它的本质是参数化类型(也就是说所操作的数据类型被指定为一个参数)。
    • 被类、接口、方法使用后就被称为:泛型类、泛型接口、泛型方法。
  • 2.为什么要有泛型?

    • 2.1 在泛型之前
      • 在泛型之前需要这么使用HashMap:
      public static void foo(){
        	Map map = new HashMap();
          map.put("泛型","大法好");
          System.out.println( (String) map.get("泛型") );
      }
      
    • 我们知道在HashMap的实现中,底层是用Object承接的key和value,所以当map.get(key)的时候,返回的是一个Object,此时只有程序员和运行中的虚拟机知道返回的应该是一个什么类型。在编译期间,编译器是无法知道Object具体是一个什么类型。而如果仅仅靠程序员来保证这项操作的正确性,是很容易将异常留存到运行期的。

    • 2.1 在泛型之后
      • 在使用泛型之后:
       public static void foo(){
          Map<String,String> map = new HashMap<>();
          map.put("泛型","大法好");
          System.out.println(map.get("泛型") );
      	}
      
    • 所以泛型在编译器对这项操作的正确性有了保证,这个作用是巨大的。

  • 3.当泛型遇上重载在这里插入图片描述

  • 3.1 为什么编译不通过?
    • 这是因为List< String > list和List< Integer > list在泛型擦除之后,变成原本的裸类型(原生类型)=List< E >。这种情况下两个方法的特征签名是一抹一样的,所以在类型擦出之后,编译不通过。
      真的这就是全部的原因吗?
  • 3.2 为什么编译又通过了?(仅可在jdk1.6编译通过)
         public static String foo1(List<String> list){
            System.out.println("foo1");
            return "";
        }
    
        public static int foo1(List<Integer> list){
            System.out.println("foo1");
            return 0;
        }
    
    • 仅仅在更改返回值时,就可以编译通过并且执行。可是返回值并不属于方法的特征签名,所以并不能作为方法重载的判定,那为什么会编译通过并执行?
    • 这是因为在class文件中,只要描述符不一致(显然,尽管方法名,参数列表都一致,但返回值并不同),两个方法就能共存,并不存在编译器中的特征签名。
    • 但讨论这些大多时候是无意义的,只是能深入的理解一下class文件的标准,在实际写代码的时候并不允许写出如此极端的重载代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值