java.lang.Class使用中文文档

Class类是反射与加载器最常用的核心类,最近计划写一个JAVA加载器框架,决定重新温习相关接口和类的源码文档,实践相关用法以消除心中所存不确定。

  • 目录结构
  1. 类说明
  2. 对象创建
  3. UML类图
  4. 类成员方法
  5. 学习总结

1 类说明

翻译Class类源码英文文档,分段翻译并配合理解和例子加深印象。

英文:Instances of the class {@code Class} represent classes and interfaces in a running Java application.
中文:在一个运行中的JAVA程序,Class类的实例,代表用关键字class或interface声明的对象,如public class AnyObjectpublic interface AnyInterface

英文:An enum is a kind of class and an annotation is a kind of interface.
中文:Enum-枚举是一种Class类型,Annotation-注解是一种接口类型

英文:Every array also belongs to a class that is reflected as a {@code Class} object that is shared by all arrays with the same element type and number of dimensions.
中文:每一个数组属于一个类,按照数组元素类型和维度被反射为一个类对象,这个类对象被具有相同元素类型和维度的数组共享。

应用理解

序号 变量声明 变量声明 是否相同 差异因素
1 String[] o1 = new String[3] String[] o2 = new String[10] 相同
2 String[] o1 = new String[3] String[][] o3 = new String[3][5] 不同 数组维度
3 String[] o1 = new String[3] byte[] o4 = new byte[1024] 不同 元素类型

英文:The primitive Java types ({@code boolean}, {@code byte}, {@code char}, {@code short},{@code int}, {@code long}, {@code float}, and {@code double}), and the keyword {@code void} are also represented as {@code Class} objects.
中文:JAVA原始类型boolean / byte / char / short / int / long / float / double 与void关键字,也都有一种类对象代表。

原始类型与类对象对应表

序号 原始类型 对象类型 类型缩写
1 boolean java.lang.Boolean Z
2 byte java.lang.Byte B
3 char java.lang.Character C
4 short java.lang.Short S
5 int java.lang.Integer I
6 long java.lang.Long J
7 float java.lang.Float F
8 double java.lang.Double D
9 void java.lang.Void V

注意:原始类型与对象类型的Class不一样,类型缩写在.class文件中用到。另外,class或interface的类型缩写为L。

2 对象创建

英文:{@code Class} has no public constructor. Instead {@code Class} objects are constructed automatically by the Java Virtual Machine as classes are loaded and by calls to the {@code defineClass} method in the class loader.
中文:Class没有公有构造器函数,虚拟机装载类对象或被调用ClassLoader的defineClass方法时,Class对象实例被JAVA虚拟机自动构造。

Class对象实例的获取方式

  • 对象实例调用getClass方法
Thread thobj = new Thread();
Class clazz = thobj.getClass();
System.out.println(clazz.getName());

对任何对象类型的实例,调用getClass()函数可以获取对象类型。

  • 类字面量.class方式
Class clazz = String.class;
System.out.println(clazz.getName());

类字面量,就是指用class关键字声明的对象名称,如public class Foo {}Foo就是这个类的类字面量。

  • 静态函数forName
Class clazz = Class.forName("java.lang.ArrayList");

请求参数为对象类型的全限定名称,一般情况,不需要额外制定类加载器。

  • 泛型类型的获取方式
Class clazz = String.class
System.out.println(clazz.getName());

3 UML类图

  • Class类声明
public final class Class implements java.io.Serializable, GenericDeclaration, Type,  AnnotatedElement {
  //主体代码
}

声明分析
1 final关键字,Class类不能被继承;
2 实现AnnotatedElement接口,支持注解功能;
3 支持泛型,Class声明,实现GenericDeclaration,支持获取泛型参数方法getTypeParameter;
4 实现Serializable接口,支持序列化。

  • Class类图
    整理Class类实现的接口,依赖的类与接口。


    ClassUML类图.png

4 类成员方法

4.1 构造函数

函数声明:private Class(ClassLoader loader)

  • 使用说明
    不能直接用new生成Class实例,也不提默认构造函数,直接由JVM在类装载或ClassLoader调用defineClass是调用。

4.2 成员方法

4.2.1 forName方法

  • 方法作用
    静态方法forName通过类的全限定名称加载类对象,常用于反射功能模块。两个函数的区别主要区别在于第二个函数制定了一个类加载器,函数实现时增加对加载器的安全权限检查。
  • 方法声明
public static Class forName(String name) throws ClassNotFoundException
public static Class forName(String name, bool isInit, ClassLoader loader) throws ClassNotFoundException

方法抛出异常还有LinkageError与ExceptionInInitializerError。
forName底层调用静态本地方法forName0函数:

private static native Class forName0(String name,  boolean isInit, ClassLoader loader, Caller caller) throws ClassNotFoundException;

4.2.2 newInstance方法

  • 方法作用
    调用默认构造函数生成对象实例。
  • 方法声明
@CallerSensitive
public T newInstance() throws InstantiationException, IllegalAccessException
  • 函数分析

注解@CallerSensitive,表明函数执行是否成功与调用者权限有关,Class类代码首先调用系统安全管理器检查调用者对本类是否有访问权限;
方法无参数,就是说,只能生成具有默认无参构造函数的类实例;若需要调用含参数列表的构造函数,需要通过反射技术调用Constructor类的newInstance方法;


4.2.3 isInstance方法

  • 方法作用
    判断本类型是否继承或实现参数制定的类或接口。
  • 方法声明
public native boolean isInstance(Object obj);

返回值说明

序号 this类型 obj说明 返回值
1 class obj是该类对象实例或子类型实例 true
2 array obj能执行类型转换为array对象 true
3 interface obj的类或上级类实现此接口 true
4 原始类型 任何情况 false

4.2.4 isAssignedFrom方法

  • 方法作用
    判断本类型是否为参数clazz的相同,或者是其子类或实现类。
  • 方法声明
public native boolean isAssignedFrom(Class clazz);

注意:与isInstance方法不同,这个参数是Class类型,而isInstance的参数是对象实例。

4.2.5 常用判断方法

public native boolean isInterface(); #判断是否为接口对象
public native boolean isArray(); #判断是否为数组对象
public native boolean isPrimitive(); #判断是否为原始类型,如byte, int等
public boolean isAnnotation(); #判断是否为注解类型
public boolean isSynthetic(); #判断是否为合成类,不是手动编写的静态类
public boolean isAnonymousClass(); #判断是否为匿名类
public boolean isLocalClass(); #判断是否为本地类
public boolean isMemberClass(); #判断是否为成员类
public boolean isEnum(); #判断是否为枚举类型

4.2.6 字段操作方法

4.2.6.1 getField

  • 方法作用
    获取类声明的公有成员变量。
  • 方法声明
@CallerSensitive
public Field getField(String name);

根据名称参数name获取类的同名字段,没有名称对应的字段将抛出NoSuchFieldException。

4.2.6.2 getFields

  • 方法作用
    获取类声明的所有公有成员变量,返回Field数组,没有成员变量返回空数组。
  • 方法声明
@CallerSensitive
public Field[] getFields() throws SecurityException;

4.2.6.3 getDeclaredField方法

  • 方法作用
    获取类声明的同名成员变量,不管是公有还是私有,没有此名称成员变量抛出异常。
  • 方法申明
public Field getDeclaredField(String name);

4.2.6.4 getDeclaredFields方法

  • 方法作用
    获取类声明的所有成员变量,无论是公有还是私有,无成员变量返回空数组。
@CallerSensitive
public Field[] getDeclaredFields() throws SecurityException;

4.2.7 构造器方法

4.2.7.1 getConstrucutor

  • 方法作用
    获取与参数列表类型匹配的公有构造函数。
  • 方法申明
@CallerSensitive
public Constructor getConstructor(Class... paramTypes) throws NoSuchMethodException, SecurityException

4.2.7.2 getDeclaredConstructor

  • 方法作用
    获取与参数列表类型匹配的构造函数,不论公有私有。
  • 方法声明
@CallerSensitive
public Constructor getDeclaredConstructor(Class... paramTypes) throws NoSuchMethodException, SecurityException

4.2.7.3 getConstructors

  • 方法作用
    获取类声明的所有公有构造函数,返回Constructor数组。
  • 方法声明
@CallerSensitive
public Constructor[] getConstructors() throws SecurityException;

4.2.7.4 getDeclaredConstructors

  • 方法作用
    获取类声明的所有构造函数,不论公有私有,返回Constructor数组。
  • 方法声明
@CallerSensitive
public Constructor[] getDeclaredConstructors() throws SecurityException;

4.2.8 成员方法函数

4.2.8.1 getMethod

  • 方法作用
    获取与参数列表类型匹配的公有方法。
  • 方法申明
@CallerSensitive
public Method getMethod(Class... paramTypes) throws NoSuchMethodException, SecurityException

4.2.8.2 getDeclaredMethod

  • 方法作用
    获取与参数列表类型匹配的方法,不论公有私有。
  • 方法声明
@CallerSensitive
public Method getDeclaredMethod(Class... paramTypes) throws NoSuchMethodException, SecurityException

4.2.8.3 getMethods

  • 方法作用
    获取类声明的所有公有方法,返回Method数组。
  • 方法声明
@CallerSensitive
public Method[] getMethods() throws SecurityException;

4.2.8.4 getDeclaredMethods

  • 方法作用
    获取类声明的所有方法,不论公有私有,返回Method数组。
  • 方法声明
@CallerSensitive
public Method[] getDeclaredMethods() throws SecurityException;

4.2.9 getModifiers方法

  • 方法作用
    获取类声明的访问修饰符,如public, protected, final等。
  • 方法声明
public native int getModifiers();

4.2.10 getInterfaces方法

  • 方法作用
    获取类实现的接口列表数组,返回Class数组, 没有实现接口返回空数组。
  • 方法声明
public Class[] getInterfaces();

4.2.11 getClasses方法

  • 方法作用
    获取类继承或实现接口的数组,返回Class数组, 没有集成与实现接口返回空数组。
  • 方法声明
public Class getClasses();

注意:getClasses方法包含getInterfaces方法返回的接口数组,排序与源代码声明顺序一致。

4.2.12 getSuperclass方法

  • 方法作用
    获取类的父类型,Class代表的类型可以是class / interface / 原始类型 / void。
  • 方法声明
public native Class getSuperclass();
  • 返回值说明
    如果this是原始类型,父类型返回null;如果this代表一个数组,父类型返回java.lang.Object。

4.2.13 getPackage方法

  • 方法作用
    返回类所在的包对象。
  • 方法声明
public Package getPackage();

4.2.14 getComponentType方法

  • 方法作用
    获取数组元素类型,如果this不是数组类型,返回null。
  • 方法声明
public native Class getComponentType()
  • 应用示例
    数组String[],函数返回数组元素类型java.lang.String。

4.2.15 getName方法

  • 方法作用
    获取this对象的全限定名称。
  • 方法声明
public String getName();
  • 应用示例
  1. 对象类型,如String.class.getName(),返回名称为java.lang.String;
  2. 原始类型,如byte.class.getName(),返回名称与原始类型一样,这里返回"byte";
  3. 数组类型,分两种情况:1)原始类型数组,返回“前缀[ + 类型缩写",如byte[5],返回字符串”[B“;2)对象数组,返回前缀[ + 类型全限定名称”,如String[5], 返回[Ljava.lang.String;
  4. 多维数组,与数组类型格式一致,数组有几维、就有几个前缀[,如long[2][3][4][5],返回字符串“[[[[J”;

4.2.16 注解操作方法

Spring / MyBatis就是调用Class类的注解操作方法,解析BEAN对象等的注解配置的,研究框架得多了解下这几个函数。

4.2.16.1 getAnnotation方法

  • 方法作用
    根据注解的类型获取类声明的注解对象。
  • 方法声明
public  A getAnnotation(Class annotationType);
  • 使用示例
@RestController("/message")
class MessageController {
    @RequestMapping(value="annotation")
    public String getAnnotation(){
        RestController obj =(RestController)this.getClass().getAnnotation(RestController.class);
        System.out.println(obj.value());
        return obj.value();
    }
}

4.2.16.2 getAnnotations方法

  • 方法作用
    获取类声明的所有注解对象,返回Annotation数组,没有注解返回空数组。
  • 方法声明
public Annotation[] getAnnotations();

4.2.16.3 isAnnotationPresent方法

  • 方法作用
    返回类是否声明annotationType参数指定的注解。
  • 方法声明
public boolean isAnnotationPresent(Annotation annotationType) ;
  • 方法示例
@Deprecated
public class App{
    public static void main(String[] args){
        /* 判断App类是否被Deprecated注解标识成Deprecated */
        boolean isOld = App.class.isAnnotationPresent(Deprecated.class);
    }
}

4.2.16.4 getAnnotationsByType方法

  • 方法作用
    根据注解类型annotationType获取类声明的所有注解,返回Annotion[]。
  • 方法声明
public  A[] getAnnotationsByType(Class annotationType)

4.3 其它函数

Class类的方法还有不少,尤其是要研究几个内部类的作用,如EnclosingMethodInfo、ReflectionData等,了解其缓存优化等特点。

5 学习总结

Class类是反射技术的核心类

掌握forName方法使用,熟练使用构造函数、成员变量、成员变量获取函数

了解getSuperclass、getClasses与getInterfaces方法使用,动态代理过程常用

熟悉注解对象操作函数,框架对象属性配置经常用到

你可能感兴趣的:(java.lang.Class使用中文文档)