泛型与反射的使用总结之泛型篇
在我看来,JDK5.0绝对是一个很具有里程碑意义的版本,在这个版本中,提供了非常多的很有价值的新特性,泛型就是其中之一,并且对反射机制进行了增强,而且5.0版本还把以前集合框架进行了重构全部添加了泛型支持。
从5.0发布到现在差不多快有10年时间了,关于这方面的知识介绍网上可以查到很多,书上也都有讲到。大象现在再写这些东西,一是将自己的经历体会总结出来作一个积累,另外一点是希望能够给刚接触这方面的童鞋一点帮助。
泛型最大的好处就是类型检查,尤其是对集合非常有用,另外在底层代码设计中很有用处,它实现了重用的功能。泛型有两种定义方式,一个是泛型类,另一个是泛型方法。
那到底什么是泛型呢?简单点讲(可能不严谨),就是用到了类型参数这样的类型变量,不管是类、接口还是方法,都可以说是用到了泛型。请看例子:
泛型类
public class Person
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
T就是类型变量,是一个参数化类型,用尖括号(<>)括起来,放在类名的后面。泛型类的类型变量可以定义多个。类型变量一般都使用一个大写字母表示,比如本例的Person
用具体的类替换类型变量就可以实例化泛型类:Person
像这样实例化是错误的:Person
泛型方法
public
return (T) getSqlSession().selectOne(key, params);
}
这是我在SSM3示例的MyBatisDao这个类里面定义的一个方法,此方法就是一个泛型方法。
但如果我改写一下,将MyBatisDao加上泛型,public class MyBatisDao
这时User的返回类型就出现编译错误了:
编译器根据MyBatisDao
类型参数的限定
对于像
上限:
下限: super T>
问号(?)叫做无限制的通配符,它可以表示任何类型。有时候使用类型变量不是那么的方便,通配符类型就很好的解决了这个问题。
super T>可以这样理解,任何T类型变量的超类型,还包括T本身,因为T可以看成是它本身的一个超类型。
那为什么说extends是上限,而extends是下限呢?通过前面两个解释就应该可以看出来,extends Serializable或者extends T说明类型变量必须是Serializable的子类和T变量的子类型,这是不是相当于限制了类型变量的上限了?同理就可以理解下限的含义了。
说了这么多关于上限和下限的东西,那他们到底有什么用?和怎么用呢?简单来讲,extends限定的类型参数可以从泛型对象读取,super限定的类型参数可以向泛型对象写入。这样说可能有些童鞋要晕了,这到底说的神马东西呢?
让我们换个方式来讲,关于泛型的上限与下限已经总结出来一个公式:PECS
PECS表示producer-extends,consumer-super
上面这个就是说如果参数化类型表示一个生产者,就用 extends T>,如果它表示一个消费者,就用 super T>。再结合上面的说明一起来理解,是不是清楚了呢?如果还不是很理解,大象再附上一小段代码来体会下其中的区别。
public void add(List extends T> list){
for(T t : list){
add(t);
}
}
public void add(T t){};
public void add(T t, List super T> list){
list.add(t);
}
泛型的擦除
泛型主要是在编译期有效,即编译的时候检查类型安全,现在写代码一般都会用Eclipse或IntelliJ,这些集成开发工具都能做到即时编译,哪里有错马上会出现红色的错误标识。因此如果出现类型转换错误,会很明显的看到结果。但是,在程序的运行阶段,JVM是不认识泛型是神马东西的,所有有泛型的类,接口,方法都会被擦除掉泛型,变成原生类型(raw type),即Person
下面就是之前的Person类用javap反编译后的结果,所有的类型变量T都被擦除掉了,因为T是一个无限定类型所以用Object替换。而且add方法中的 extends T>和 super T>也被去掉了。
public class com.bolo.Person extends java.lang.Object{
private java.lang.Object t;
public com.bolo.Person();
public java.lang.Object getT();
public void setT(java.lang.Object);
public void add(java.util.List);
public void add(java.lang.Object);
public void add(java.lang.Object, java.util.List);
}
因此针对泛型擦除这一特点,我们需要注意这样几点:
1、JVM里面没有泛型,只有普通的类和方法。
2、所有的类型参数都用限定类型或者无限定类型用Object来替代。
3、请谨慎处理方法重载,错误的使用重载不会实现想要的多态。
4、为保证类型安全,必要时请使用强制类型转换。
泛型的限制
基本类型不能作为类型参数。Person
类型检查只能用原始类型。if(t instanceof Person) 如果写成if(t instanceof Person
不能实例化类型变量。这样写是错误的:T t = new T()
不能实例化参数化类型的数组。Person
不能定义静态实例变量和静态方法。如果你想这样写:private static T a 那对不起,编译器马上会给你一个错误提示。
其实关于泛型的限制完全可以不用讲,现在编译器都很强大,只要你这样做了,马上会给你显示一个错误。
最后说下泛型对于集合的用处来说是最大的,集合是一个容器,有了泛型就更方便重用。而我们使用最频繁的集合就是List列表,还有一个容器就是数组,大象在这里强烈建议大家多用List,尽量或最好不要用数组。其一是List有类型安全性检查,其二是数组的功能List都提供了并且更丰富,其三List对gc进行了优化。如果使用数组,特别是操作对象数组,如果经验不足,没有释放数组里面的对象引用,则很容易造成内存泄漏的问题。
更多泛型与反射的使用总结之泛型篇相关文章请关注PHP中文网!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Le chargement de classe de Java implique le chargement, la liaison et l'initialisation des classes à l'aide d'un système hiérarchique avec Bootstrap, Extension et Application Classloaders. Le modèle de délégation parent garantit que les classes de base sont chargées en premier, affectant la classe de classe personnalisée LOA

L'article examine la mise en œuvre de la mise en cache à plusieurs niveaux en Java à l'aide de la caféine et du cache de goyave pour améliorer les performances de l'application. Il couvre les avantages de configuration, d'intégration et de performance, ainsi que la gestion de la politique de configuration et d'expulsion le meilleur PRA

L'article discute de l'utilisation de JPA pour la cartographie relationnelle des objets avec des fonctionnalités avancées comme la mise en cache et le chargement paresseux. Il couvre la configuration, la cartographie des entités et les meilleures pratiques pour optimiser les performances tout en mettant en évidence les pièges potentiels. [159 caractères]

L'article discute de l'utilisation de Maven et Gradle pour la gestion de projet Java, la construction de l'automatisation et la résolution de dépendance, en comparant leurs approches et leurs stratégies d'optimisation.
