Java Reflection-Classes

原文连接:http://tutorials.jenkov.com/java-reflection/classes.html

通过使用 Java 反射,我们可以在程序运行时来观察 Java classes 。通常我们使用 Java 反射最先会观察 classes ,通过 classes 我们可以获取到的信息有:

  • The Class Object
  • Superclass
  • Modifiers
  • Package Info
  • Implemented Interfaces
  • Implemented Interfaces
  • Constructors
  • Methods
  • Fields
  • Annotations

还有 Java classes 相关的更多信息。我们可以参考 JavaDoc for java.lang.Class 来获取更全面的信息。本文将对上面提到的所有的知识点作一个简单的涉及。上面列出的一些主题将会在单独的部分做一个更详细的介绍。比如,本文将会向大家展示怎样获取所有的 method 或者是一个特定的 method ,但会在专门的一篇文章中来介绍怎样调用那个特定的 method ,如果有多个同名的 method 怎样根据 method 名称和给定的 method 参数来匹配找到我们想要找的那个特定的 method ,调用 Java 反射的方法会抛出什么异常,怎样发现一个get、set方法等。本文的主要目的就是基本的介绍一下 Class 对象以及我们可以从该对象中获取到哪些信息。

The Class Object

要想使用某一个 class 的 Java 反射我们首先得获得该 class 的 java.lang.Class 对象。在 Java 中所有的类型包括原生类型(int、long、float等)、数组都有一个与之相关联的  Class 对象。在编译期如果我们能知道一个 Java class ,我们就可以通过下面的方法来获取到一个 Class 对象:

Class aClass = User.class;

如果在编译期我们不知道 Class 名,但我们在程序运行时能获得 class 的字符串全名,我们可以通过下面的代码来得到一个 Class 对象:

String className = "test.User";
Class aClass = Class.forName(className);

Class Name

当我们通过使用 Class.forName() 方法来获取一个 Class 对象时,我们传递的这个 className 必须是一个 class 的全名(包括所有的包名)。比如, User 位于包 test 下,那么全名就是 test.User ,如果 User 位于 com.model.test 包下,那么 class 的全名就是 com.model.test.User 。
Class.forName()  这个方法在程序运行时如果在 classpath 路径下找不到那个 class ,会抛出一个 ClassNotFoundException 异常。

从一个 Class 对象中我们可以获取到它的两种名称。我们可以通过 getName() 方法来获取到一个 class 的全名(包括包名):

String className = "test.User";
Class aClass = Class.forName(className);
String fullName = aClass.getName();

如果我们只想获得一个 class 的名称而不需要获取包名我们可以通过调用 getSimpleName() 方法来达到目的:

String className = "test.User";
Class aClass = Class.forName(className);
String simpleName = aClass.getSimpleName();

Modifiers

我们可以通过 Class 对象来获取到一个 class 的访问修饰符(private、public、static等),我们可以通过下面的方式来获取访问修饰符:

int modifiers = aClass.getModifiers();

modifiers是所有访问修饰符标识位的一个整型表示的集合(学过linux的同学都会知道,linux中有权限这一说,有三种权限读、写、执行即r、w、x,可以分别用4、2、1来代表,如果给定一个整数是7,7=4+2+1,那么代表的权限就是读、写、执行,如果给定的整数是1,那么代表的权限一定是执行,如果给定的整数是6,6=4+2,那么代表的权限一定是读、写等等)。我们可以通过java.lang.reflect.Modifier的以下方法来检查一个class的访问修饰符:

Modifier.isAbstract( modifiers);
Modifier.isFinal( modifiers);
Modifier.isInterface( modifiers);
Modifier.isNative( modifiers);
Modifier.isPrivate( modifiers);
Modifier.isProtected( modifiers);
Modifier.isPublic( modifiers);
Modifier.isStatic( modifiers);
Modifier.isStrict( modifiers);
Modifier.isSynchronized( modifiers);
Modifier.isTransient( modifiers);
Modifier.isVolatile( modifiers)

Package Info

我们可以通过以下的代码来获取一个 Class 对象的包信息:

String className = "test.User";
Class aClass = Class.forName(className);
Package aPackage = aClass.getPackage();

通过 Package 对象我们可以获取到包的信息,比如可以获取到包名。我们也可以获取到位于 classpath 下的 JAR 包中专门用于具体说明这个包的的 Manifest 文件。 java.lang.Package 的详细信息

Superclass

通过Class对象我们可以获取到class对象的父类,下面是代码实现:

String className = "test.User";
Class aClass = Class.forName(className);
Class superClass = aClass.getSuperclass();

superclass 对象就像其他的 Class 对象一样,我们也可以在 superclass 对象上继续对其进行反射。

Implemented Interfaces

通过下面的代码我们可以获取到一个给定的class实现的的所有接口:

String className = "test.User";
Class aClass = Class.forName(className);
Class[] interfaces = aClass.getInterfaces();

在 Java 反射中 Class 对象也可以代表接口,一个 class 可以实现多个接口,因此调用 aClass.getInterfaces() 方法会返回来一个类型为Class的数组。
注意:只有被给定的一个 class 所声明实现的那些特定接口才会被返回。如果被给定的那个 class 所继承的父类实现的接口,但所给定的那个 class 并没有再特殊声明实现了接口,在返回的数组中是不包含这一类的接口的。尽管事实上被给定的那个 class 实现了那些接口,因为通过调用父类的getInterfaces() 方法会返回这些接口,所以在子类中调用 getInterfaces() 方法就不会返回那些接口了。
为了完整的获取到一个给定的 class 的所有接口,我们可以通过调用给定的 class 的 getInterfaces()和 递归的调用它的父类getInterfaces()。

Constructors

我们可以通过下面的方式来获取到一个 class 的所有构造方法:

Constructor[] constructors = aClass.getConstructors();

在后面我们会写一篇介绍 Constructors 的文章来详细的介绍构造方法。

Methods

我们可以通过下面的方式来获取到一个 class 的所有方法:

Method[] method = aClass.getMethods();

在后面我们会写一篇介绍 Methods 的文章来详细的介绍它。

Fields

我们可以通过下面的方式来获取到一个 class 的所有字段:

Field[] method = aClass.getFields();

在后面我们会写一篇介绍 Fields 的文章来详细的介绍它。

Annotations

Annotation[] annotations = aClass.getAnnotations();

我们可以在后面我们会写一篇介绍 Annotations 的文章来详细的介绍它。

你可能感兴趣的:(java)