-
泛型( 以下代码仅可在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 >。这种情况下两个方法的特征签名是一抹一样的,所以在类型擦出之后,编译不通过。
真的这就是全部的原因吗?
- 这是因为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文件的标准,在实际写代码的时候并不允许写出如此极端的重载代码。
【Java基础】泛型与泛型擦除
最新推荐文章于 2023-10-13 23:12:05 发布