使用Java反射机制可以在运行时期检查Java类的信息,检查Java类的信息往往是你在使用Java反射机制的时候所做的第一件事情,通过获取类的信息你可以获取以下相关的内容:
Class对象(java.lang.Class)
类名
修辞符(private,public,protect)
包信息
父类
实现的接口
构造器(Constructor)
方法(Method)
变量(Field)
注解(Annotation)
先来简单概括,然后再分开扩展。
Class对象
在你想检查一个类的信息之前,你首先需要获取类的Class对象。Java中的所有类型包括基本类型(int, long, float等等),即使是数组都有与之关联的
Class类的对象。如果你在编译期知道一个类的名字的话,那么你可以使用如下的方式获取一个类的Class对象。
1 |
Class myObjectClass = MyObject. class ; |
如果你在编译期不知道类的名字,但是你可以在运行期获得到类名的字符串,那么你则可以这么做来获取Class对象:
1 |
String className = ... ; //在运行期获取的类名字符串 |
2 |
Class class = Class.forName(className); |
在使用Class.forName()方法时,你必须提供一个类的全名,这个全名包括类所在的包的名字。例如MyObject类位于com.jenkov.myapp包,那么他
的全名就是com.jenkov.myapp.MyObject。如果在调用Class.forName()方法时,没有在编译路径下(classpath)找到对应的类,那么将会抛出
ClassNotFoundException。
类名
你可以从Class对象中获取两个版本的类名。
通过getName() 方法返回类的全限定类名(包含包名):
1 |
Class aClass = ... //获取Class对象,具体方式可见Class对象小节 |
2 |
String className = aClass.getName(); |
如果你仅仅只是想获取类的名字(不包含包名),那么你可以使用getSimpleName()方法:
1 |
Class aClass = ... //获取Class对象,具体方式可见Class对象小节 |
2 |
String simpleClassName = aClass.getSimpleName(); |
修饰符
可以通过Class对象来访问一个类的修饰符,即public,private,static等等的关键字,你可以使用如下方法来获取类的修饰符:
1 |
Class aClass = ... //获取Class对象,具体方式可见Class对象小节 |
2 |
int modifiers = aClass.getModifiers(); |
修饰符都被包装成一个int类型的数字,这样每个修饰符都是一个位标识(flag bit),这个位标识可以设置和清除修饰符的类型。
可以使用java.lang.reflect.Modifier类中的方法来检查修饰符的类型:
01 |
Modifier.isAbstract( int modifiers); |
02 |
Modifier.isFinal( int modifiers); |
03 |
Modifier.isInterface( int modifiers); |
04 |
Modifier.isNative( int modifiers); |
05 |
Modifier.isPrivate( int modifiers); |
06 |
Modifier.isProtected( int modifiers); |
07 |
Modifier.isPublic( int modifiers); |
08 |
Modifier.isStatic( int modifiers); |
09 |
Modifier.isStrict( int modifiers); |
10 |
Modifier.isSynchronized( int modifiers); |
11 |
Modifier.isTransient( int modifiers); |
12 |
Modifier.isVolatile( int modifiers); |
包信息
可以使用Class对象通过如下的方式获取包信息:
1 |
Class aClass = ... //获取Class对象,具体方式可见Class对象小节 |
2 |
Package package = aClass.getPackage(); |
通过Package对象你可以获取包的相关信息,比如包名,你也可以通过Manifest文件访问位于编译路径下jar包的指定信息,比如你可以在
Manifest文件中指定包的版本编号。更多的Package类信息可以阅读java.lang.Package。
父类
通过Class对象你可以访问类的父类,如下例:
1 |
Class superclass = aClass.getSuperclass(); |
可以看到superclass对象其实就是一个Class类的实例,所以你可以继续在这个对象上进行反射操作。
实现的接口
可以通过如下方式获取指定类所实现的接口集合:
1 |
Class aClass = ... //获取Class对象,具体方式可见Class对象小节 |
2 |
Class[] interfaces = aClass.getInterfaces(); |
由于一个类可以实现多个接口,因此getInterfaces();方法返回一个Class数组,在Java中接口同样有对应的Class对象。
注意:getInterfaces()方法仅仅只返回当前类所实现的接口。当前类的父类如果实现了接口,这些接口是不会在返回的Class集合中的,尽管
实际上当前类其实已经实现了父类接口。
构造器
你可以通过如下方式访问一个类的构造方法:
1 |
Constructor[] constructors = aClass.getConstructors(); |
更多有关Constructor的信息可以访问Constructors。
方法
你可以通过如下方式访问一个类的所有方法:
1 |
Method[] method = aClass.getMethods(); |
更多有关Method的信息可以访问Methods。
变量
你可以通过如下方式访问一个类的成员变量:
1 |
Field[] method = aClass.getFields(); |
更多有关Field的信息可以访问Fields。
注解
你可以通过如下方式访问一个类的注解:
1 |
Annotation[] annotations = aClass.getAnnotations(); |
更多有关Annotation的信息可以访问Annotations。
原文地址:Java Reflection(二):Classes