Java核心技术知识点笔记—泛型程序设计
Posted lykAnd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java核心技术知识点笔记—泛型程序设计相关的知识,希望对你有一定的参考价值。
1、泛型方法:
(1)定义:泛型方法的定义方式,将类型变量放在修饰符的后面,返回类型的前面。
public class TestGenericC
public <T> void test(T t)
System.out.print(t);
如上,在一个普通类中定义了一个泛型方法。
(2) 调用:当调用一个泛型方法时,在方法名前的尖括号中放入具体的类型:
public class Main
public static void main(String[] args)
TestGenericC genericC = new TestGenericC();
genericC.<String>test("generic test");
大多数情况下,尖括号中的类型参数可以省略,编译器有足够的信息能够推断出所调用的方法。(如上例,编译器使用names的类型(即String[])与泛型类型T[]进行匹配并推断出T一定是String。)
2、泛型代码和虚拟机
虚拟机没有泛型类型对象:所有对象都属于普通类。
2.1、类型擦除:定义一个泛型类型都自动提供了一个相应的原始类型(raw type)。原始类型的名字就是删去类型参数后的泛型类型名。擦除(erased)类型变量,并替换为限定类型(无限定的用Object替换)。
public class TestGenericC<T> //泛型类型
private T first;
private T second;
public class TestGenericC //原始类型
private Object first;
private Object second;
如上所示,TestGenericC的泛型类型T没有限定,因此它的原始类型用Object来替换。如果对T有所限定,则使用第一个限定的类型变量来替换。如:
public class TestGenericC<T extends Comparable & Serializable> //泛型类型
private T first;
private T second;
public class TestGenericC //原始类型
private Comparable first;
private Comparable second;
对类型T做了限定,原始类型中使用第一个限定类型Conparable来进行替换。为了提高效率,应该将标签(tagging)接口(没有方法的接口)放在边界列表的末尾。
2.2、翻译泛型表达式:当程序调用泛型方法时,如果擦除返回类型,编译器插入强制类型转换。例如:
public class TestGenericC<T> //泛型类型
private T first;
public T getFirst()
return first;
public class Main
public static void main(String[] args)
TestGenericC<String> genericC = new TestGenericC();
String first = genericC.getFirst();
擦除getFirst的返回类型后返回Object类型,编译器自动插入String的强制类型转换。就是说,编译器把这个方法调用翻译为两条虚拟机指定:
(1)对原始方法TestGenericC.getFirst的调用;
(2)将返回的Object类型强制转换为String类型。
当存取一个泛型域时(如上例的first)一样要插入强制类型转换。
2.3、翻译泛型方法:(详见:《Java核心技术》卷1(原书第10版)第318页)
2.4、注意点:
(1)虚拟机中没有泛型,只有普通的类和方法;
(2)所有的类型参数都用它们的限定类型替换;
(3)桥方法被合成来保持多态;
(4)为保持类型安全性,必要时插入强制类型转换。
给大忙人看的Java核心技术笔记(6泛型编程)
要点:
泛型类是带有一个或多个类型参数的类
泛型方法是带有类型参数的方法
可以要求类型参数必须是一个或者多个类型的子类型
泛型类型是不变得:当S是T的子类型是,G<S>和G<T>没有关系
通过使用通配符G<? extends T>或者 G<? super T>,你可以指定一个方法接受一个带子类或父类参数的泛型类型的实例
当泛型类和方法被编译时,类型参数会被擦除
类型擦除对泛型有诸多限制。特别是,不能实例化泛型类或数组。不能转换成泛型类型,或者抛出一个泛型类型对象。
即使泛型类和方法在虚拟机中被擦除,你也可以在运行时找出他们是如何声明的。
1、泛型类
※类型参数不能用基本类型实例化。例如Entry<String, int>在Java中是无效的。
当构造一个泛型类对象时,可以在构造函数中省略类型参数。
1 Entry<String, Integer> entry = new Entry<>("1",1);
2、泛型方法
当声明一个反洗方法时,类型参数要放在修饰符之后,返回类型之前。当调用时,不要指定类型参数。它可以从方法的参数和返回类型中推断出来。
也可以在调用时候显示的写出来
1 public static <T> void swap(T[] array, int i, int j); 2 Arrays.<String>swap(friends,0,1);
3、类型限定
泛型类或方法的类型参数需要满足某些要求,或者是需要能够调用一些通用的方法。可以对类型做出限定。
T extends AutoCloseable
类型参数可以有多个限定: T extends Runnable & AutoCloseable
※可以有多个接口限定,但最多只能有一个是类。如果有一个限定是类,则它必须放在限定列表的第一位。
以上是关于Java核心技术知识点笔记—泛型程序设计的主要内容,如果未能解决你的问题,请参考以下文章