Java 程序在运行时,Java 运行时系统一直对所有的对象进行所谓的运行时类型标识。Class 类封装一个对象和接口运行时的状态,当装载类时,Class 类型的对象自动创建。
Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的,因此不能显式地声明一个 Class 对象。
虚拟机为每种类型管理一个独一无二的 Class 对象。也就是说,每个类(型)都有一个 Class 对象。运行程序时,Java 虚拟机 (JVM) 首先检查是否所要加载的类对应的 Class 对象是否已经加载。如果没有加载,JVM 就会根据类名查找.class 文件,并将其 Class 对象载入。Class 对象包含着类的元数据(metadata)包括类的
- name
- package
- methods
- fields
- constructors
- annotations
基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也都对应一个 Class 对象。枚举是 class,而 注解 (annotation) 是 interface。
获取 Class 对象
有如下方法可以获取 Class 对象
- 直接使用 MyClass.class 来获取,一般当类没有实例时可以直接通过这种方式来获取
- 如果类已经申明了实例 myClass,则可以通过实例方法
myClass.getClass()
方法来获取 - 通过 Class 类的静态方法
forName()
来获取,比如Class.forName("MyClass")
,传入的参数必须是接口或者类的名字
Class 类常用方法
getName()
getName()
方法返回 String,Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。
getConstructors()
获取类所有公开的构造函数数组,返回 Constructor<?>[]
newInstance()
通常在反射中为类创建实例。newInstance
调用默认构造函数(无参)来初始化新建对象。
getSuperclass()
返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。
获取构造函数
Class API | 列表 | 私有构造函数 |
---|---|---|
getDeclaredConstructor() | no | yes |
getConstructor() | no | no |
getDeclaredConstructors() | yes | yes |
getConstructors() | yes | no |
获取成员变量
Class API | 成员变量列表 | 继承的变量 | 私有变量 |
---|---|---|---|
getDeclaredField() | no | no | yes |
getField() | no | yes | no |
getDeclaredFields() | yes | no | yes |
getFields() | yes | yes | no |
获取类方法
Class API | 方法列表 | 继承的方法 | 私有方法 |
---|---|---|---|
getDeclaredMethod() | no | no | yes |
getMethod() | no | yes | no |
getDeclaredMethods() | yes | no | yes |
getMethods() | yes | yes | no |
综上基本看到出来:不带 Declared
的方法都是返回的类公开的 public 可访问的,而带 Declared
的方法能够访问私有。
而对于继承的方法或者变量,通过不带 Declared
的方法能够访问到。
其他方法
public static Class<?> forName(String className)// 传入完整的“包,类”名称实例化 Class 对象
public Constructor[] getContructors() // 得到一个类的全部的构造方法
public Field[] getDeclaredFields()// 得到本类中单独定义的全部属性
public Field[] getFields()// 得到本类继承而来的全部属性
public Method[] getMethods()// 得到一个类的全部方法
public Method getMethod(String name,Class..parameterType)// 返回一个 Method 对象,并设置一个方法中的所有参数类型
public Class[] getInterfaces() // 得到一个类中锁实现的全部接口
public String getName() // 得到一个类完整的“包。类”名称
public Package getPackage() // 得到一个类的包
public Class getSuperclass() // 得到一个类的父类
public Object newInstance() // 根据 Class 定义的类实例化对象
public Class<?> getComponentType() // 返回表示数组类型的 Class
public boolean isArray() // 判断此 class 是否是一个数组
反射
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为 java 语言的反射机制。一直以来反射技术都是 Java 中的闪亮点,这也是目前大部分框架(如 Spring/Mybatis 等)得以实现的支柱。在 Java 中,Class 类与 java.lang.reflect 类库一起对反射技术进行了全力的支持。在反射包中,我们常用的类主要有 Constructor 类表示的是 Class 对象所表示的类的构造方法,利用它可以在运行时动态创建对象、Field 表示 Class 对象所表示的类的成员变量,通过它可以在运行时动态修改成员变量的属性值(包含 private)、Method 表示 Class 对象所表示的类的成员方法,通过它可以动态调用对象的方法(包含 private)。
reference
- Java doc