1. 为什么要使用泛型
因为
1)使用泛型意味着编写的代码可以被很多个不同类型的对象所重用。
2)使用泛型之后可以减少类型转换的风险
2.泛型类
1) 类定义中的类型变量指定了方法的返回类型以及域和局部变量的类型。
2) 在生成泛型类的实例时,没有强制要求要去设置其类型参数,只是不设置类型参数时,会给出警告:
如"Test is a raw type. References to generic type Test<T> should be
parameterized"
3.泛型方法
1) 泛型方法可以定义在普通类中,也可以定义在泛型类中
2)泛型方法的调用,有2种方式,一般使用第2种方式。如:
//1. 在方法前加上<String>
ArrayAlg.<String>getMiddle(names);
//2. 在方法不加上<String>,编译器会推断出T的类型是String,这样调用也不会有警告提示
ArrayAlg.getMiddle(names);
4.泛型限定
1)目的: 使用泛型边界控制(泛型限定)是为了使用T上的方法,如果不限定则不能调用T上的任何代码。
例:T extends Comparable 表明T只能是实现了Comparable接口的类或者接口。这是对泛型边界的控制。
这时就可以调用T上的compareTo方法,因为编译器知道T实现了omparable接口。
2)一个类型变量可以有多个限定,如:
T extends Comparable & Serializable,多个限定之间使用&分割。
3)跟java的继承一样,对泛型的限定只能有一个是限定类,可以多个限定接口,并且限定类必须放在类型变量的
限定中的第一个
如:T extends boundTypeClass1 & inteface1 & interface2
如果是 T extends boundTypeClass1 & boundTypeClass2 则会报错
5.泛型代码与虚拟机
1)虚拟机没有泛型类型对象,所有的对象都是普通对象。如,没有ArrayList<String>.class 和ArrayList<Integer>.class
的区别,二者在虚拟机中都是Arraylist.class.即泛型类型的信息在jvm中被擦除了(也即类型参数被擦除)。 泛型的信息只能在.java文件中看到,jvm编译后的.class文件中没有泛型的信息。
2)当定义一个泛型类型时, jvm都会自动地为该泛型提供一个相应的原始类型(raw type).原始类型的名字就是删除类型参数后的
泛型类型名。如:Pair<String>的原始类型就是Pair.
3)在jvm中,泛型类型变量会被擦除,并替换为限定类型,如果没有指定限定类型,在替换为Object。如Pair<T>,因没有指定限
定类型,所以类Pair中所有的T会被替换成Object. 如 方法 public T getFirst(){return first} 会被替换成public Object getFirst(){return first}.
如果指定了限定,那么原始类型会用第一个限定类型的变量来替换。如:
public class Interval<T extends Comparable & Serializable> implement Serializble{
public Interval(T first , T second){
....
}
private T lower;
private T upper;
}
原始类型Interval替换后如下(也即类中的T被第一个泛型限定Comparable替换):
public class Interval implement Serializble{
public Interval(Comparable first , Comparable second){
....
}
private Comparable lower;
private Comparable upper;
}
6. 将泛型变量赋给普通变量和把普通变量赋给泛型变量的问题。
Thinking in javaP395, 泛型对象赋给普通对象,不会有警告,但是把普通对象赋给泛型对象会有警告。
7. java泛型需要考虑的一些限制
1) 不能用基本类型实例化参数类型。如没有Pair<double>,只有Pair<Double>.
2) 运行时类型查询只使用于原始类型。如if(a instanceof Pair<String> ) 跟if(a instanceof Pair) 是一样的
3) 参数化数组不合法。如 Pair<String>[] ps = new Pair<String>[10]; //error
但是在方法返回的时候可以返回 T[];
4) 不能实例化类型变量
如: new T() 或 T.class;//error.
5) 泛型类的静态上下文中类型变量无效。
如声明一个 public static T getxxx(){}的方法会报错。
8. 泛型的协变和逆变,即: <T extends SomeType > 和<T super SomeType>
1)协变和逆变的作用:
是在两个泛型之间建立某种类型的向上转型关系。因为普通类的继承关系直接在泛型中使用是行不通的。
如:Number 是Integer 的父类。Number n = new Integer();这种使用方式没有问题,但是如果有一个泛型接口
public interface Box<T> {
public T get();
public void put(T element);
public void put(Box<T> box);
}
注:BoxImpl代码省略
Box<Integer> iBox = new BoxImpl<Integer>(3);
Box<Number> nBox = iBox;
上面的语句会报错。但是使用
Box<? extends Number> nBox = iBox; 就可以了。
2)注意事项:
协变只能取数据,不能set数据。因为取出来的数据,至少是Number。
而Box<? extends Number> nBox = new BoxImpl<Integer>(3); 也可以赋值为
Box<? extends Number> nBox = new BoxImpl<Double>(3), 所以设置值时,编译器不知道是Integer,还是 Double,故设置值出错。
而逆变则相反,可以设置数据,不能用于取数据
9. 无界通配符<?>
1)为什么要用无界通配符?
个人感觉用处不大,唯一能体会到的用处是:在使用遗留代码或者一些第3方工具类的时候,去掉非泛型代码的警告。如
Query query = "";
List resultList = query.getResultList();
该句会有警告。因为getResultList不是泛型化的List,但是可以使用以下语句来去除警告:
List<?> resultList = query.getResultList();
10. 类继承中的泛型, 只能使用下面的几种方式来声明。
class Myclass<T> extends Base<T> // 同时声明T
class Myclass extends Base<String> //父类确定类型
class Myclass extends Base //都不声明类型。
相关推荐
17.2.5 泛型总结.mp4
Java 中泛型总结 Java 中泛型总结是指在 Java 语言中使用泛型(generics)来实现编译时类型安全检测机制,避免向下转型的隐患。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。在 Java 中,...
### C#泛型总结 #### 一、泛型概述 泛型是C# 2.0及之后版本引入的一项重要特性,它允许开发者在编写类、接口或方法时使用类型参数,这种机制允许代码能够在不知道具体类型的情况下工作,并在编译时确保类型安全性...
C#泛型是一种强大的编程工具,它为C#程序员提供了更大的灵活性和性能优化。泛型在.NET Framework 2.0中被引入,旨在解决传统集合类(如ArrayList)在处理不同类型数据时存在的性能和类型安全问题。以下是关于C#泛型...
Java泛型是Java SE 5.0引入的一个重要特性,极大地提高了代码的类型安全性和重用性。在本文中,我们将深入探讨Java泛型的进阶概念,包括通配符、边界、类型擦除以及在实际开发中的应用。 1. 通配符 通配符在Java...
Java 泛型是Java语言中一个重要的特性,它允许开发者在编写代码时就对容器(如List、Set、Map等)中的数据类型进行约束,从而增强了类型安全性和代码的可读性。以下是对Java泛型的详细解释: 1. **泛型类型**:泛型...
关于java泛型的总结: 从入门介绍到项目使用的实际经验归纳总结得出! 从jdk5到jdk8!
Java泛型机制详解 Java泛型是Java语言中的一种机制,用于在编译期检查类型安全。Java泛型的出现解决了Java早期版本中类型安全检查的缺陷。Java泛型的好处是可以在编译期检查类型安全,避免了运行时的...
Java 泛型总结(二):泛型与数组 Java 中泛型数组的关系确实有些复杂,不允许直接创建泛型数组,本文将分析其中的原因,并总结一些创建泛型数组的方式。 首先,让我们看看数组和泛型的关系。数组相比于 Java ...
"Java 泛型总结(一):基本用法与类型擦除" Java 泛型是 Java 语言中的一种强大功能,它可以使代码更加简洁、安全。下面是对 Java 泛型的基本用法和类型擦除机制的介绍。 泛型的基本用法 ------------- 泛型是...
Java 泛型总结(三):通配符的使用 通配符是 Java 泛型中一个重要的概念,它允许我们在泛型中实现向上转型,解决了泛型不支持协变的问题。本文将详细介绍通配符的使用和原理。 在 Java 中,数组是协变的,这意味...
思维导图之Java泛型详解
Java 泛型是一种强大的编程工具,它允许在类、接口和方法中使用类型参数,以增强类型安全性和代码重用性。泛型的引入解决了Java集合框架中存储和操作不同类型的对象时可能出现的问题,比如类型转换异常(`...
总结来说,C#中的泛型为我们提供了编写灵活且高效代码的能力。泛型类和泛型方法可以提高代码的复用性,泛型接口确保了接口实现的一致性,而泛型委托则增强了函数式编程的能力。在实际项目中,熟练运用这些泛型特性...
泛型是Java编程语言中的一个重要特性,它引入了类型参数的概念,使得代码更加安全,同时提高了重用性。本文将深入探讨泛型的应用、原理、协变与逆变以及泛型缓存等核心知识点。 首先,让我们理解泛型的基本概念。...
Java泛型是Java编程语言中的一个关键特性,它在2004年随着JDK 5.0的发布被引入,极大地增强了代码的类型安全性和重用性。泛型允许我们在编写类、接口和方法时指定参数化类型,使得代码在编译时期就能捕获类型错误,...