大家好呀!我是小笙!我学习了韩顺平老师的类和对象的知识,收获颇丰!现在来和大家分享笔记!
基本介绍
Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。
泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
泛型特点
-
可以使用任意字母A-Z T 是 type的缩写,比较常用
class Template<E>{
E filed;
@Override
public String toString() {
return "Template{" +
"filed=" + filed +
'}';
}
public E method(){
return filed;
}
public Template(E filed) {
this.filed = filed;
}
}
-
只能指代引用类型的数据 -
在给泛型指定具体类型后,可以传入该类型或者其子类类型 public class Generic02 {
public static void main(String[] args) {
C<A> C = new C<A>(new A());
C<A> C2 = new C<A>(new B());
}
}
class A{}
class B extends A{}
class C<E>{
E c;
public C(E c) {
this.c = c;
}
}
-
泛型的使用形式 ArrayList<Integer> arrayList = new ArrayList<Integer>();
ArrayList<Integer> arrayList2 = new ArrayList<>();
ArrayList arrayList = new ArrayList();
分析泛型编译后的文件
java里面的泛型只存在于源代码里面,一旦经过编译之后,所有的泛型都会被擦除掉,全部被替换为原来的裸类型,并在对元素进行访问和修改的时候,才会加上强制类型转换。
public class Test {
public static void main(String[] args) {
ArrayList<String> sList = new ArrayList<String>();
ArrayList<Integer> iList = new ArrayList<Integer>();
System.out.println(sList.getClass() == iList.getClass());
}
}
public class Generic02 {
public static void main(String[] args) {
C<A> C = new C<A>(new A());
C<A> C2 = new C<A>(new B());
A a = C.c;
}
}
class A{}
class B extends A{}
class C<E>{
E c ;
E[] e;
public C(E c) {
this.c = c;
}
}
public class com/Al_tair/generic_/Generic02 {
public static main([Ljava/lang/String;)V
L0
LINENUMBER 9 L0
NEW com/Al_tair/generic_/C
DUP
NEW com/Al_tair/generic_/A
DUP
INVOKESPECIAL com/Al_tair/generic_/A.<init> ()V
INVOKESPECIAL com/Al_tair/generic_/C.<init> (Ljava/lang/Object;)V
ASTORE 1
L1
LINENUMBER 10 L1
NEW com/Al_tair/generic_/C
DUP
NEW com/Al_tair/generic_/B
DUP
INVOKESPECIAL com/Al_tair/generic_/B.<init> ()V
INVOKESPECIAL com/Al_tair/generic_/C.<init> (Ljava/lang/Object;)V
ASTORE 2
L2
LINENUMBER 11 L2
RETURN
GETFIELD com/Al_tair/generic_/C.c : Ljava/lang/Object;
CHECKCAST com/Al_tair/generic_/A
L3
......
}
类型擦除的缺点
1.使用类型擦除直接导致了对于原始的数据类型无法支持,比如int,long这种,因为java不支持Object类型和基本数据类型之间的强制类型转换,也就是说一旦类型擦除之后,就没法在进行 类型转换了。也正是这样,现在的泛型都是不支持原始类型的,比如ArrayList,而不能使用ArrayList。
2.运行期间无法获得泛型类型信息。因为泛型都被擦除了,都被替换成了裸类型。这样就导致了下面的程序都会报错,比如无法使用泛型来创建对象,或者数组。
自定义泛型
自定义泛型类
基本语法
class 类名<泛型>{}
注意细节
自定义泛型接口
基本语法
interface 接口名<泛型>{}
注意细节
- 静态成员中不能使用类的泛型
- 泛型接口的类型是在实现接口的时候确定的
- 没有指定类型,则默认为Object类型
自定义方法
基本语法
修饰符<泛型>返回类型 方法名(参数列表){}
public void XXX(E e){}
注意细节
- 泛型方法可以放在普通类或者泛型类中
- 方法在使用之前,类型必须确定
泛型的继承和同配符
- 泛型不具有继承性
- <?> : 支持任意类型
- <? extends A> :支持A 类以及A类的子类,规定了泛型的上限
- <> super A> ;支持A类以及A类的父类,规定了泛型的下限
相关面试题
什么是泛型?泛型的作用?
- Java 泛型(Generics)是 JDK 5 中引入的一个新特性。
- 使用泛型参数,可以增强代码的可读性以及稳定性。编译器可以对泛型参数进行检测,并且通过泛型参数可以指定传入的对象类型。比如
ArrayList<Persion> persons = new ArrayList<String>() 这行代码就指明了该ArrayList 对象只能传入 Persion 对象,如果传入其他类型的对象就会报错。 - 可以用于构建泛型集合。原生
List 返回类型是 Object ,需要手动转换类型才能使用,使用泛型后编译器自动转换。
推荐面试题
|