Java泛型-Android面试准备2019-1-23

接口

接口到底是干什么的?答:接口是用来指明相关或者不相关类的多个对象的共同行为(共同方法)。例如,使用正确的接口,可以指明这些对象是可比较的、可食用的、以及可克隆的等等。

泛型

泛型使我们可以定义带泛型类型的类或接口或方法,随后编译器会用具体的类型来替换它。

优点:能够在编译时而不是在运行时检测出错误,因此可以提高软件的可靠性和可读性。其实很好理解,我们自定义一个整型栈类,栈类里面是一个ArrayList,如果ArrayList里面元素类型使用Object,此时无论是Integer类还是String类的实例都可以放进去,但是应该放进去Integer类实例,如果传错了(譬如传了一个String类实例)将不会报错,但使用了泛型的话,在编译时就会报错。

注意:泛型类型必须是引用类型,不能使用基本数据类型(int,double,char)来替换泛型类型,但可以使用Integer,这时可以传入一个int,Java会将其包装为Integer,这个过程称作自动打包。同样,如果元素是包装类型(Integer,Double,Character),那么可以直接将这个元素赋给一个基本类型的变量,这个过程称为自动拆箱。

定义泛型类:

为了定义一个类为泛型类型,需要将泛型类型放在类名之后,例如StringStack

注意:为了创建一个字符串堆栈,可以使用new StringStack(),但需要注意定义这个类的构造方法时不写泛型标识,应该被定义为public StringStack() {},即不进行显式定义,使用Java默认提供的无参构造方法即可。

定义泛型方法:

为了定义一个方法为泛型类型,要将泛型类型放在方法返回类型之前,例如 void printMax(E o1, E o2)。

可以为静态方法定义泛型类型。

Java泛型-Android面试准备2019-1-23_第1张图片
泛型方法的定义与调用
Java泛型-Android面试准备2019-1-23_第2张图片
受限的泛型类型

通配泛型:

1.为什么需要通配泛型?

首先,Integer是Number的子类。我们现在定义了一个方法用来找到栈中的最大值,签名是public static double max(GenericStack stack),如果这时有一个类型为GenericStack的栈实例integerStack,语句int a = max(integerStack)会报错,因为integerStack不是GenericStack的实例。尽管Integer是Number的子类型,但是GenericStack并不是GenericStack的子类型,这时我们需要通配泛型类型。

2.通配泛型类型

通配泛型类型有三种:?(非受限通配符)、? Extends T()或者? super T。

?称为非受限通配,它和? extends Object是一样的。? Extends T()称为受限通配,表示T或T的一个子类型。? super T称为下限通配,表示T或T的一个父类型。

将上面的函数签名改为public static double max(GenericStack stack)即可,是一个表示Number或Number子类型的通配类型。

消除泛型:

编译器可使用泛型信息,但这些信息在运行时是不可用的,这被称为类型消除。编译器使用泛型类型信息来编译代码,但是随后会消除它,即泛型信息在运行时是不可用的。泛型存在于编译时,一旦编译器确认泛型类型是安全使用的,就会将它转换为原始类型。

例子:

将a编译成b

Java泛型-Android面试准备2019-1-23_第3张图片

如果一个泛型类型是受限的,那么编译器就会用该受限类型来替换它。

例子:

将a编译成b

Java泛型-Android面试准备2019-1-23_第4张图片

非常需要注意的是,不管实际的具体类型是什么,泛型类是被它的所有实例所共享的。

Java泛型-Android面试准备2019-1-23_第5张图片
Java泛型-Android面试准备2019-1-23_第6张图片

你可能感兴趣的:(Java泛型-Android面试准备2019-1-23)