文章来源:https://blog.csdn.net/sybnfkn040601/article/details/73602346
https://cloud.tencent.com/developer/article/1353161
getSuperclass :
返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。如果此 Class 表示 Object 类、一个接口、一个基本类型或 void,则返回 null。如果此对象表示一个数组类,则返回表示该 Object 类的 Class 对象。
getGenericSuperclass :
返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的直接超类的Type。如果超类是参数化类型,则返回的 Type 对象必须准确反映源代码中所使用的实际类型参数。如果以前未曾创建表示超类的参数化类型,则创建这个类型。有关参数化类型创建过程的语义,请参阅 ParameterizedType 声明。如果此 Class 表示 Object 类、接口、基本类型或 void,则返回 null。如果此对象表示一个数组类,则返回表示 Object 类的 Class 对象。
两个方法都是获取超类的类型 .
看一个例子 :
打印结果 :
这两者都能获取父类的类型 .
但是如果我们换成下面形式, 我们就可以找到两个方法差别。
上面的方法, 我们使用”getGenericSuperclass()”方法获取父类的类型, 然后重新读一遍该方法的说明 “如果超类是参数化类型,则返回的 Type 对象必须准确反映源代码中所使用的实际类型参数 ” . 也就是这种方式可以获取超类的参数类型, 也就是泛型中的”Integer”类型 .
但是如果上面方法我们使用”getSuperclass() “方法就会出现类型转换错误”java.lang.Class cannot be cast to java.lang.reflect.
ParameterizedType”,
再举一个例子:
父类:
package com.itheima.mytest; public class Person<T1, T2> { }
子类:
package com.itheima.mytest; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; public class Student extends Person<Integer, String> { @SuppressWarnings("rawtypes") public static void main(String[] args) { Student student = new Student(); // getClass() 获得该类的类类型(即类型变量) Class clazz = student.getClass(); // getSuperclass() 获得该类的父类 System.out.println(clazz.getSuperclass()); // getGenericSuperclass() 获得该类带有泛型的父类 Type type = clazz.getGenericSuperclass(); System.out.println(type); // Type是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。 // ParameterizedType 参数化类型,即泛型 // 将Type转化为参数化类型(即泛型) ParameterizedType p = (ParameterizedType) type; // getActualTypeArguments() 获取参数化类型的数组,泛型可能有多个 Type[] actualTypeArguments = p.getActualTypeArguments(); // 将Type转化为类型变量(即Class) Class c1 = (Class) actualTypeArguments[0]; Class c2 = (Class) actualTypeArguments[1]; System.out.println(c1); System.out.println(c2); } }
运行结果
class com.itheima.mytest.Person com.itheima.mytest.Person<java.lang.Integer, java.lang.String> class java.lang.Integer class java.lang.String
记得以前使用hibernate时候, 我们会为所有Dao创建一个BaseDao, 将一般的增删改查操作抽取到BaseDao中 .
下面就是一个例子 :
我们将增删改查一般操作放在BaseDao中, 但是在”查”过程中, 遇到问题 . 当使用Hibernate拼写HQL时候, 查一张表需要知道这张表对应的对象的名称 . 比如”t_user”对应”User” . 那么在HQL中需要使用”User” . 但是在父类BaseDao中如何获取子类操作什么类型对象(UserDao操作User, DepartmentDao操作Department),
上面构造方法中, 就是获取的方式, 重点是利用泛型然后使用反射里的”getGenericSuperclass”方法, 就可以获取到对应的类型 . 进而获取对应的className 。