总体而言,泛型(通用类型)是一个好东西,它是一个工程上起到好处的东西,对于性能、安全等并没有什么帮助。
在java工程上,泛型属于必须掌握的,理由如下:
1.各种源码中基本上都有泛型,无论是java基础源码照旧Spring大概阿帕奇的。不掌握这个,你读不懂。你没有方法饶过它
2.有了泛型,某种程度上会让代码更清楚和简便
注意:本文中很多地方“泛型”和“通用类型”交叉使用,其中后者居多,二者都是表示java中的Generic Type。
通用类型,不是表示该类型通用,可以用用于恣意地方,而是表示类的参数类型是不定的。
一、泛型界说
在oracle的官方文档中的形貌:
A generic type is a generic class or interface that is parameterized over types
详细页面地址:https://docs.oracle.com/javase/tutorial/java/generics/index.html
Generic有通用,一般的意思。
其实翻译为通用类型也许更妥当一些,大概可参数化类型。
以上的一句话的意思:通用类型是允许参数化类型的类/接口。
反过来的意思就是:如果一个类/接口不允许对其属性类型举行参数化处理,那么就不是通用的。
Java泛型是在Java 5(也称为JDK 1.5)中首次引入的,这一版本在2004年发布。泛型的引入是Java编程语言的一个重要里程碑。
它允许步伐员在编写类、接口和方法时指定类型参数,使得编译器可以在编译时检查类型安全,从而避免了类型转换异常,进步了代码的可读性和可维护性。
泛型的主要特性包括:
类型参数化:允许类或接口在界说时指定一个或多个类型参数,这些类型参数在实例化时会被详细的类型所替换。
类型检查:在编译时举行类型检查,确保类型安全。
类型推断:从Java 7开始,引入了菱形操作符,简化了泛型实例化的语法,并且编译器可以或许自动推断泛型类型。
泛型方法:可以在方法级别上界说泛型,而不仅仅是在类级别上。
有界类型参数:通过extends和super关键字对类型参数举行限制,确保类型参数是某个特定类或接口的子类型或超类型。
自Java 5引入泛型以来,Java的后续版本(如Java 6、Java 7、Java 8等)对泛型举行了进一步的完善和增强。
例如,Java 7引入了菱形操作符,简化了泛型实例化的语法;Java 8增强了泛型的类型推断能力。这些改进使得Java的泛型更加易用和强大。
总的来说,Java泛型的引入是Java编程语言发展的一个重要里程碑,它极大地进步了Java代码的类型安全性和可维护性。
以上内容是文心一言总结出来的,认真看了下,没有什么毛病,注意几点:
1.重要里程碑-考虑到通用类型在java的源码中如此常见,可以肯定的这是名副其实
2.类型推断、编译器- 是的,现实干活的主要是编译器,不是运行时也不是编码时候,工程师只要关注其优缺点和使用场景即可
通用类型的几个关键词/符号:T,?,,extends,super
其中T(也可以是恣意正当的字母、词汇,例如 GOGO,DODO,P,X,Y之类的)表示类型,表示特定类型的占位符,在实例化对象的时候需要指定T的详细类型。
其中?是占位符,表示恣意类型(有肯定限制),通常和extends/super组合使用,也可以单独使用(多在方法代码区域)
它们的组合可以是:
- 表示不定类型,通常用于方法
- 表示不定类型,可用于类大概方法中
- ? extends T ,表示T的恣意子类,通常用于方法
- ? super T,表示T的恣意父类(祖类...),通常用于方法
- T extends E,表示T是E的恣意子类,可以用于方法和类
- T super E,表示T是E的父祖类,主要用于方法
- T ,表示结果类型的逼迫转换,统称用于方法
- T 通常用于方法参数大概表示返回类型
以上几种都必须牢记,建议通过java自有代码和本身编写例子来强化记忆。
需要特别注意的是,组合虽然多,但是照旧有很多限制的。 通用类型的实现端赖JCP解释,所以为什么这个行,谁人
不行,并没有太多的理由,就好像为什么有引力。但随着java版本的迭代,通用类型有望得到更好的支持。
通用类型本质上在于:
1.限定/泛化方法的参数类型 -用在方法上,通常是限定参数类型
2.限定/泛化类成员的类型 -用在类上,通常是为了限定成员类型
二、通用类型经典例子(list)
2.1 ArrayList
以下是ArrayList的几个典型界说,包含了类的界说,其中5个是方法上的。- 1.public class ArrayList<E> extends AbstractList<E>
- implements List<E>, RandomAccess, Cloneable, java.io.Serializable;
- 2.public E get(int index);
- 3.public ArrayList(Collection<? extends E> c);
- 4.public void forEachRemaining(Consumer<? super E> action);
- 5.public Object clone() {
- try {
- <strong>ArrayList</strong><strong><?> v = (ArrayList<?>) super</strong><strong>.clone();</strong>
- v.elementData = Arrays.copyOf(elementData, size);
- v.modCount = 0;
- return v;
- } catch (CloneNotSupportedException e) {
- // this shouldn't happen, since we are Cloneable
- throw new InternalError(e);
- }
- };
- 6.public boolean removeAll(Collection<?> c);
复制代码 这里都是经典的用法:限定类的特定类型/类型范围。
有一个稍微特殊的例clone()(上文第5):
ArrayList v = (ArrayList) super.clone();
考虑到返回的是Object类型,v界说为恣意类型都是可以的,例如 ArrayList v。
那么JCP这里为什么要写成而不是?
2.2、其它
- -- jdbcTemplate
- 1.public <T> T queryForObject(String sql, Class<T> requiredType) throws DataAccessException {
- return queryForObject(sql, getSingleColumnRowMapper(requiredType));
- }
- 2.public <T> List<T> queryForList(String sql, Class<T> elementType) throws DataAccessException {
- return query(sql, getSingleColumnRowMapper(elementType));
- }
- -- Stream
- <R, A> R collect(Collector<? super T, A, R> collector);
- public final Stream<P_OUT> limit(long maxSize) {
- if (maxSize < 0)
- throw new IllegalArgumentException(Long.toString(maxSize));
- return SliceOps.makeRef(this, 0, maxSize);
- }<br>-- jdk.internal.vm.vector.VectorSupport<br>
复制代码 注:为了节省篇幅,对原文做了一些裁剪。
1.编译时候的类型检查
2.消除类型转换 -也就是有些人说的类型擦除,类型替换(为现实类型)
3.编写通用算法
这些是经典的作用,也是最主要的作用。
3.2、局限性
它有浩繁局限性,这些局限性可以归纳为一点:不能恣意地在类界说、方法和变量中随意地使用通用类型干系的符号
1.不能在方法的参数中如许界说--方法中的通用类型符号只能跟在详细的类型之后用于限定某个类型
do(? extends T xx)
do( |