Better

业精于勤荒于嬉

Java反射2-类

Better's Avatar 2017-02-22 Java译文

  1. 1. Class类
  2. 2. 类名
  3. 3. 修饰符
  4. 4. 包信息
  5. 5. 父类
  6. 6. 实现的接口
  7. 7. 构造器
  8. 8. 成员变量
  9. 9. 注解
  • The Class Object
  • Class Name
  • Modifiers
  • Package Info
  • Superclass
  • Implemented Interfaces
  • Constructors
  • Methods
  • Fields
  • Annotations

Java反射使得你能在运行时检查类信息。一般来说反射常用的方式是检查类的信息。你能获取到的类信息有:

  • Class Name(类名)
  • Class Modifies(修饰符),public,private,synchronized等。
  • Package Info(包信息)
  • Superclass(父类)
  • Implemented Interfaces(实现的接口)
  • Constructors(构造器)
  • Methods(方法)
  • Fields(成员变量)
  • Annotation(注解)

加上等多的Java类相关信息。更多的信息请看JavaDoc for java.lang.Class。本文会简明的阐释上面提到的信息,更加详细的阐述上面的一些主。例如在本文将教你如何获取所有类的方法或者指定的方法,但是在其他章节将教你如何使用获取到的方法,怎样去发现你指定参数与之匹配的方法,以及如果存在多个具有相同方法名称的方法,怎样去找到你指定参数的方法,执行反射出来的放回会抛出什么异常,如何发现getter和setter方法。本文旨在介绍CLass类以及你通过Class类你能获取到上面信息。

Class类

在你获取类信息之前你先要获取到Class类对象。在Java语言里面所有的类包括基本的变量(int,long,float等)以及数组都包含Class类对象( have an associated Class object)。在编译期间,如果你知道一个类的名称你就能获取一个Class对象,像这样:
Class myObjectClass = MyObject.class
如果在编译期间你不知道类名,你知道类的全路径名称你可以像这样获取Class对象:

1
2
String className = ... //程序运行时获取Class对象 
Class class = Class.forName(className);

当我们使用Class.forName()方法的时候你必须知道类的权路径名称。就是类的包名信息。比如,MyObject类是在包com.jenkov.myapp中那么全路径就是com.jenkov.myapp.MyObject
如果一个类没有被找到,程序运行时Class.forName()方法会抛出ClassNotFoundException异常。

类名

从一个类(Class)对象你又两种方式获取类名。
全路径名称(包含包名信息)是通过getName()方法:

1
2
Class aClass =...//获取类对象
String className = aClass.getName();

如果不想获取全路径名称只想获取类名可以通过getSimpleName()方法获取:

1
2
Class  aClass          = ... //obtain Class object. See prev. section
String simpleClassName = aClass.getSimpleName();

修饰符

通过Class对象你能获取到类的修饰符。类的修饰符包括“public”,“private”,“static”等待。

1
2
Class  aClass = ... //obtain Class object. See prev. section
int modifiers = aClass.getModifiers();

修饰符已整形的方式返回,其值是被Java预想定义好的。你可以通过java.lang.reflect.Modifier的方法来判断到达时那种修饰符:

1
2
3
4
5
6
7
8
9
10
11
12
Modifier.isAbstract(int modifiers)
Modifier.isFinal(int modifiers)
Modifier.isInterface(int modifiers)
Modifier.isNative(int modifiers)
Modifier.isPrivate(int modifiers)
Modifier.isProtected(int modifiers)
Modifier.isPublic(int modifiers)
Modifier.isStatic(int modifiers)
Modifier.isStrict(int modifiers)
Modifier.isSynchronized(int modifiers)
Modifier.isTransient(int modifiers)
Modifier.isVolatile(int modifiers)

包信息

你可以通过一下方式Class对象获取包信息:

1
2
Class  aClass = ... //obtain Class object. See prev. section
Package package = aClass.getPackage();

通过Package对象你能获取到他的路径。也能获取到在Manifest中指定JAR包指定的信息。你可以通过java.lang.Package了解具体的信息。

父类

比如:

1
Class superclass = aClass.getSuperclass();

获取到的父类的Class对象就其他的Class一样,你可以继续获反射出类的其他信息。

实现的接口

我们可以回去到类实现的接口:

1
2
Class  aClass = ... //obtain Class object. See prev. section
Class[] interfaces = aClass.getInterfaces();

类能实现很多的接口方法。因此以数组的形式返回类实现的接口方法。接口也是可以通过Java反射找到的。
注意:反射只能找到被当前类实现了的接口。如果父类实现的接口方法,子类如果没有重载改方法,是不会再数组中返回。即使这个类拥有这个方法,因为他的父类实现了它。
所以为了得到一个类的所有接口方法,你必须的递归类和他的父类以及父类的父类。

构造器

获取构造器的方式大概是这样:

Constructor[] constructors = aClass.getConstructors();
更多关于构造器的描述请见:Constructors

成员变量

获取变量域的方式大概是这:
Field[] method = aClass.getFields();
更多信息:Fields

注解

Annotation[] annotations = aClass.getAnnotations();
更多信息:Annotations

原文

This article was last updated on days ago, and the information described in the article may have changed.