本文已参与「新人创作礼」活动,一起开启掘金创作之路。
我们根据这篇文章中的示例类结构来完成下面内容的介绍。
获取类的基本信息
一个自定义类中包含很多信息,如包名、类名、父类、实现的接口等等。java 中的反射特性给我们提供了很多的api,我们来看一下。
Class clazz = Class.forName("xxxx.xxxx.xxxx.Student");
// 获取包名+类名
System.out.println(clazz.getName());
// 只获取类名
System.out.println(clazz.getSimpleName());
// 只获取包名
System.out.println(clazz.getPackage());
// 获取当前类的父类
System.out.println(clazz.getSuperclass());
// 判断当前类是否为内部类
System.out.println(clazz.isAnonymousClass());
// 判断一个类是否为另一个类的子类
System.out.println(Animal.class.isAssignableFrom(clazz));
// 判断当前类是否为抽象类
System.out.println(Modifier.isAbstract(clazz.getModifiers()));
// 判断当前结构是否是一个接口
System.out.println(clazz.isInterface());
实例化类对象的几种方式
我们使用反射的特性,调用类中的构造方法来完成示例化对象的操作。我们介绍以下三种方式。
调用类的无参构造方法来实例化对象:
Class<?> clazz = Student.class;
Student student;
try {
//调用该类的无参构造方法
student = (Student) clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
执行上述代码的时候,在终端会输出
non parameter construct method
这就代表,newInstance 方法会调用当前类的无参构造方法来完成对象的创建。
调用类的有参构造方法来实例化对象
我们依旧通过一个例子来看如何使用。
Class<?> clazz = Student.class;
Student student;
try {
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
student = (Student) constructor.newInstance("Jack", 47);
} catch (Exception e) {
e.printStackTrace();
}
上面代码中,clazz.getConstructor(String.class, int.class) 就是用来获取该Student 类中的参数类型为String 和int 的构造方法。
执行上述代码后,终端会输出结果为
age: 47 name: Jack
这代表在获取类的对象的时候,调用了类的有参构造函数。
如何获取一个类的所有构造方法
其实在一个类中,构造方法有时候会有很多,反射特性也提供了相应的api 来获取某个某个类的所有构造函数,同时我们也可以获得到构造函数中所需要的参数。我们继续通过例子来看一下。
Class<?> clazz = Student.class;
for (Constructor<?> constructor : clazz.getConstructors()) {
for (Class<?> parameterType : constructor.getParameterTypes()) {
System.out.println(parameterType);
}
}
也就是通过clazz.getConstructors()就可以获取到类的所有的构造方法。
对于某个构造函数,调用getParameterTypes 方法就可以获得到这个构造方法的参数类型。
总结
这篇文章我们介绍了如何通过反射获取类的基本信息,以及如何通过反射构造实例化的对象。