咱们能够经过已知的包名来获取到 Class 对象,从而能够经过反射动态的来操做对象。
获取Class有三种方式java
//经过对象.class直接获取 Class integerClass = Integer.class; //根据包名,经过Class.forName方法获取class Class integerClass = Class.forName("java.lang.Integer"); //根据包名,经过classloader.loadClass方法获取class Class integerClass = this.getClass().getClassLoader().loadClass("java.lang.Integer");
接下来根据实际的例子说明一下编程
public interface InterfaceA { void interfaceAMethodA(int a); } public interface InterfaceB { Double interfaceBMethodB(int a, String b); } public class ClassA implements InterfaceA { private int classAFieldA; @Override public void interfaceAMethodA(int a) { } //省略了 getter setter 方法 } public class ClassB extends ClassA implements InterfaceB{ private String classBFieldB; @Override public Double interfaceBMethodB(int a, String b) { return null; } //省略了 getter setter 方法 }
运行一个测试方法数组
public static void main(String[] args) { Class clazz = Class.forName("org.dmgnn.reflect.ClassB"); System.out.println("clazz.getGenericSuperclass() = " + JSON.toJSONString(clazz.getGenericSuperclass())); System.out.println("clazz.getSuperclass() = " + JSON.toJSONString(clazz.getSuperclass())); Arrays.stream(clazz.getMethods()).forEach(m -> { System.out.println("clazz.getMethods() -> " + m.getName() + " getParameterTypes -> " + JSON.toJSONString(m.getParameterTypes()) + " getReturnType -> " + m.getReturnType()); }); Arrays.stream(clazz.getDeclaredMethods()).forEach(m -> { System.out.println("clazz.getDeclaredMethods() -> " + m.getName() + " getParameterTypes -> " + JSON.toJSONString(m.getParameterTypes()) + " getReturnType -> " + m.getReturnType()); }); System.out.println("clazz.getInterfaces() = " + JSON.toJSONString(clazz.getInterfaces())); System.out.println("clazz.getGenericInterfaces() = " + JSON.toJSONString(clazz.getGenericInterfaces())); } //输出 clazz.getGenericSuperclass() = "org.dmgnn.reflect.ClassA" clazz.getSuperclass() = "org.dmgnn.reflect.ClassA" clazz.getMethods() -> equals getParameterTypes -> ["java.lang.Object"] getReturnType -> boolean clazz.getMethods() -> toString getParameterTypes -> [] getReturnType -> class java.lang.String clazz.getMethods() -> hashCode getParameterTypes -> [] getReturnType -> int clazz.getMethods() -> builder getParameterTypes -> [] getReturnType -> class org.dmgnn.reflect.ClassB$ClassBBuilder clazz.getMethods() -> interfaceBMethodB getParameterTypes -> ["int","java.lang.String"] getReturnType -> class java.lang.Double clazz.getMethods() -> getClassBFieldB getParameterTypes -> [] getReturnType -> class java.lang.String clazz.getMethods() -> setClassBFieldB getParameterTypes -> ["java.lang.String"] getReturnType -> void clazz.getMethods() -> interfaceAMethodA getParameterTypes -> ["int"] getReturnType -> void clazz.getMethods() -> getClassAFieldA getParameterTypes -> [] getReturnType -> int clazz.getMethods() -> setClassAFieldA getParameterTypes -> ["int"] getReturnType -> void clazz.getMethods() -> wait getParameterTypes -> ["long","int"] getReturnType -> void clazz.getMethods() -> wait getParameterTypes -> ["long"] getReturnType -> void clazz.getMethods() -> wait getParameterTypes -> [] getReturnType -> void clazz.getMethods() -> getClass getParameterTypes -> [] getReturnType -> class java.lang.Class clazz.getMethods() -> notify getParameterTypes -> [] getReturnType -> void clazz.getMethods() -> notifyAll getParameterTypes -> [] getReturnType -> void clazz.getDeclaredMethods() -> equals getParameterTypes -> ["java.lang.Object"] getReturnType -> boolean clazz.getDeclaredMethods() -> toString getParameterTypes -> [] getReturnType -> class java.lang.String clazz.getDeclaredMethods() -> hashCode getParameterTypes -> [] getReturnType -> int clazz.getDeclaredMethods() -> canEqual getParameterTypes -> ["java.lang.Object"] getReturnType -> boolean clazz.getDeclaredMethods() -> builder getParameterTypes -> [] getReturnType -> class org.dmgnn.reflect.ClassB$ClassBBuilder clazz.getDeclaredMethods() -> getClassBFieldB getParameterTypes -> [] getReturnType -> class java.lang.String clazz.getDeclaredMethods() -> interfaceBMethodB getParameterTypes -> ["int","java.lang.String"] getReturnType -> class java.lang.Double clazz.getDeclaredMethods() -> setClassBFieldB getParameterTypes -> ["java.lang.String"] getReturnType -> void clazz.getInterfaces() = ["org.dmgnn.reflect.InterfaceB"] clazz.getGenericInterfaces() = ["org.dmgnn.reflect.InterfaceB"]
getGenericSuperclass() 和 getSuperclass() 返回父类class
getMethods() 返回当前class以及父类class的全部方法 getDeclaredMethods 返回当前class的方法 getInterfaces() 和 getGenericInterfaces() 返回当前class实现的接口编程语言
getGenericSuperclass() 和 getSuperclass() 虽然都是返回的父类class,可是2个方法的返回类型不同。ide
public Type getGenericSuperclass() { ClassRepository info = getGenericInfo(); if (info == null) { return getSuperclass(); } // Historical irregularity: // Generic signature marks interfaces with superclass = Object // but this API returns null for interfaces if (isInterface()) { return null; } return info.getSuperclass(); } public native Class<? super T> getSuperclass();
getSupperClass() 返回的是Class<? super T>
getGenericSuperClass() 返回的是 Type测试
/** * Type is the common superinterface for all types in the Java * programming language. These include raw types, parameterized types, * array types, type variables and primitive types. * * @since 1.5 */ public interface Type { /** * Returns a string describing this type, including information * about any type parameters. * * @implSpec The default implementation calls {@code toString}. * * @return a string describing this type * @since 1.8 */ default String getTypeName() { return toString(); } }
从注释来看,Type 接口是 Java 编程语言中全部类型的通用超级接口。这些包括原始类型,参数化类型,数组类型,类型变量和基本数据类型。 已知的子接口有 GenericArrayType, ParameterizedType, TypeVariable<D>, WildcardTypeui
ParameterizedType 定义为this
public interface ParameterizedType extends Type { //返回的对象的实际类型参数 Type表明这种类型的数组。 Type[] getActualTypeArguments(); //返回表示的类或接口声明此类型的 Type对象。 Type getRawType(); //返回一个表示该类型的成员 Type对象类型。 Type getOwnerType(); }
看注释有点看不懂,再看一个例子日志
public class ClassC<T1, T2> { public void printType() { System.out.println("clazz.getGenericSuperclass() = " + JSON.toJSONString(getClass().getGenericSuperclass())); System.out.println("clazz.getActualTypeArguments() = " + JSON.toJSONString(((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments())); } } public class ClassD extends ClassC<Integer, String> { } public static void main(String[] args) { ClassD classD = new ClassD(); classD.printType(); } //输出 clazz.getGenericSuperclass() = {"actualTypeArguments":["java.lang.Integer","java.lang.String"],"rawType":"org.dmgnn.reflect.ClassC","typeName":"org.dmgnn.reflect.ClassC<java.lang.Integer, java.lang.String>"} clazz.getActualTypeArguments() = ["java.lang.Integer","java.lang.String"]
clazz.getGenericSuperclass() 获取到的是ClassD的父类,也就是ClassC<T1, T2>,这个类接收2个泛型参数。
经过打印出来的日志看到已经获取到了ClassC实际运行时的参数(actualTypeArguments)类型为<Integer, String>,也就是ClassD在继承的时候传到ClassC的参数,原型(rawType)为 org.dmgnn.reflect.ClassC,完整的类名(typeName)为 org.dmgnn.reflect.ClassC<java.lang.Integer, java.lang.String>
那么想要得到ClassC在运行的时的泛型类型,只要调用getActualTypeArguments()方法便可。code