获取Class类的实例

  • 若已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高。
    Class clazz = Person.class;
  • 已知某个类的实例,调用该实例的getClass()方法获取Class对象。
    Class clazz = person.getClass();
  • 已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可抛出ClassNotFoundException。
    Class clazz = Class.forName(“demo1.Student”);
  • 内置基本数据类型可以直接用类名.Type。
  • 还可以利用ClassLoader。

有了Class对象,能做什么?

  • 创建类的对象,调用Class对象的newInstance()方法
  • 类必须有一个无参数的构造器。
  • 类的构造器访问权限需要足够。
  • 思考?难道没有无参的构造器就不能创建对象了吗?只要在操作的时候明确的调用类中的构造器,并将参数传递进去之后,才可以实例化操作。
  • 1):通过Class类的getDeclaredConstructor(Class … parameterTypes)取得本类的指定形参类型的构造器。
  • 2):向构造器的形参中传递一个对象数字进去,里面包含了构造器中所需要的参数。
  • 3):通过Constructor实例化对象。

调用指定的方法

通过反射,调用类中的方法,通过Method类完成。

  • 通过Class类的getMethod(String name,Class…parameterTypes)方法取得一个Method对象,并设置此方法操作时所需要的参数类型。
  • 之后使用Object invoke(Object obj,Object[] args)进行调用,并向方法中传递要设置的obj对象的参数信息。
  • Object对应原方法的返回值,若原方法无返回值,此时返回null
  • 若原方法为静态方法,此时形参Object obj可为null
  • 若原方法形参列表为空,则Object[] args为null
  • 若原方法声明为private,则需要在调用invoke()方法前,显式调用方法对象的setAccessible(true)方法,将可访问private的方法

反射操作泛型

  • Java采用泛型擦除的机制来引入泛型,Java中的泛型仅仅是给编译器javac使用的,确保数据的安全性和免去强制类型转换问题,但是,一旦编译完成,所有和泛型有关的类型全部擦除
  • 为了通过反射操作这些类型,Java新增了ParameterizedType,GenericArrayType,TypeVariable和WildcardType几种类型来代表不能被归一到Class类中的类型但是又和原始类型齐名的类型。
  • ParameterizedType:表示一种参数化类型,比如Collection。
  • GenericArrayType:表示一种元素类型是参数化类型或者类型变量的数组类型。
  • TypeVariable:是各种类型变量的公共父接口。
  • WildcardType:代表一种通配符类型表达式。