Java反射API研究(3)——java.lang.Class<T>
对于反射来说,Class是核心,任何反射的对象都需要通过Class来获得。
Class
类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class
对象。基本的 Java 类型(boolean
、byte
、char
、short
、int
、long
、float
和 double
)和关键字 void
也表示为 Class
对象。
Class
没有公共构造方法。Class
对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass
方法自动构造的。
Class<T>的T
- 由此 Class
对象建模的类的类型。例如,String.class
的类型是 Class<String>
。如果将被建模的类未知,则使用 Class<?>
。
下面来看看如何获得一个类的Class对象。
有以下几种方式:
1、调用一个实例的getClass()方法,这个方法是从Object继承下来的,任何一个对象的实例都可以通过getClass()方法来获取当前实例的类的Class对象,如果声明时是父类,则获取的是真实实例的Class,即子类的Class。
2、通过一个Class对象的Class.getSuperclass(),获取其父类的Class对象
3、Class的静态方法forName(String class),这个最常用,通过类名包括包名获取一个类的class对象,还有个重载方法forName(String name, boolean initialize, ClassLoader loader),第二个参数表示是否初始化该类,即是否执行该类的静态代码段,forName(String class)调用的这个方法,默认为true,初始化该类的静态方法。这在注册jdbc驱动时有用到。
4、通过一个类的静态成员获取class对象,类名.class即可。这个成员对象是jvm加上去的。
5、primitive wrapper classes的TYPE 语法,包装类可以通过包装类的TYPE静态变量来获取。这里要注意一下:
int.class == Integer.TYPE,但是int.class != Integer.class。经过包装后,包装类和原始类的class不是一个对象。
Class对象的所有方法:
<U> Class<? extends U> | asSubclass(Class<U> clazz) | 强制转换该 Class 对象,以表示指定的 class 对象所表示的类的一个子类。 |
T | cast(Object obj) | 将一个对象强制转换成此 Class 对象所表示的类或接口。 |
boolean | desiredAssertionStatus() | 如果要在调用此方法时将要初始化该类,则返回将分配给该类的断言状态。 |
static Class<?> | forName(String className) | 返回与带有给定字符串名的类或接口相关联的 Class 对象。 |
static Class<?> | forName(String name, boolean initialize, ClassLoader loader) | 使用给定的类加载器,返回与带有给定字符串名的类或接口相关联的 Class 对象。 |
AnnotatedType[] | getAnnotatedInterfaces() | 返回注释的AnnotatedType |
AnnotatedType | getAnnotatedSuperclass() | 返回父类的注解的AnnotatedType |
<A extends Annotation> A | getAnnotation(Class<A> annotationClass) | 如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。 |
Annotation[] | getAnnotations() | 返回此元素上存在的所有注释。 |
<A extends Annotation> A[] | getAnnotationsByType(Class<A> annotationClass) | 返回一个该类型的注解数组 |
String | getCanonicalName() | 返回 Java Language Specification 中所定义的底层类的规范化名称。 |
Class<?>[] | getClasses() | 返回类定义的公共的内部类,以及从父类、父接口那里继承来的内部类 |
ClassLoader | getClassLoader() | 返回该类的类加载器。 |
Class<?> | getComponentType() | 返回表示数组组件类型的 Class。如果此类表示数组类,返回表示此类组件类型的 Class。否则返回null。 |
Constructor<T> | getConstructor(Class<?>... parameterTypes) | 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。 |
Constructor<?>[] | getConstructors() | 返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。 |
<A extends Annotation> A | getDeclaredAnnotation(Class<A> annotationClass) | 返回直接存在于此元素上的该类型注释。 |
Annotation[] | getDeclaredAnnotations() | 返回直接存在于此元素上的所有注释。 |
<A extends Annotation> A[] | getDeclaredAnnotationsByType(Class<A> annotationClass) | 返回直接存在于此元素上的该类型的注解数组。 |
Class<?>[] | getDeclaredClasses() | 返回类定义的公共的内部类,不包括继承的。 |
Constructor<T> | getDeclaredConstructor(Class<?>... parameterTypes) | 根据指定参数类型顺序返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。可获取非公共构造方法。 |
Constructor<?>[] | getDeclaredConstructors() | 返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。不仅是公共的。 |
Field | getDeclaredField(String name) | 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。 |
Field[] | getDeclaredFields() | 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。 |
Method | getDeclaredMethod(String name, Class<?>... parameterTypes) | 返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。 |
Method[] | getDeclaredMethods() | 返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。 |
Class<?> | getDeclaringClass() | 如果此 Class 对象所表示的类或接口是另一个类的成员,则返回的 Class 对象表示该对象的声明类。即返回所在类的class对象,对成员class对象有效。 |
Class<?> | getEnclosingClass() | 返回底层类的立即封闭类。 |
Constructor<?> | getEnclosingConstructor() | 如果该 Class 对象表示构造方法中的一个本地或匿名类,则返回 Constructor 对象,它表示底层类的立即封闭构造方法。 |
Method | getEnclosingMethod() | 如果此 Class 对象表示某一方法中的一个本地或匿名类,则返回 Method 对象,它表示底层类的立即封闭方法。 |
T[] | getEnumConstants() | 如果此 Class 对象不表示枚举类型,则返回枚举类的元素或 null。 |
Field | getField(String name) | 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。 |
Field[] | getFields() | 返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。 |
Type[] | getGenericInterfaces() | 返回表示某些接口的 Type,这些接口由此对象所表示的类或接口直接实现。 |
Type | getGenericSuperclass() | 返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的直接超类的 Type。 |
Class<?>[] | getInterfaces() | 确定此对象所表示的类或接口实现的接口。 |
Method | getMethod(String name, Class<?>... parameterTypes) | 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。 |
Method[] | getMethods() | 返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。 |
int | getModifiers() | 返回此类或接口以整数编码的 Java 语言修饰符。 |
String | getName() | 以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。 |
Package | getPackage() | 获取此类的包。 |
ProtectionDomain | getProtectionDomain() | 返回该类的 ProtectionDomain。 |
URL | getResource(String name) | 查找带有给定名称的资源。 |
InputStream | getResourceAsStream(String name) | 查找具有给定名称的资源。 |
Object[] | getSigners() | 获取此类的标记。 |
String | getSimpleName() | 返回源代码中给出的底层类的简称。 |
Class<? super T> | getSuperclass() | 返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。 |
String | getTypeName() | 返回该类型的名称 |
TypeVariable<Class<T>>[] | getTypeParameters() | 按声明顺序返回 TypeVariable 对象的一个数组,这些对象表示用此 GenericDeclaration 对象所表示的常规声明来声明的类型变量。 |
boolean | isAnnotation() | 如果此 Class 对象表示一个注释类型则返回 true。 |
boolean | isAnnotationPresent(Class<? extends Annotation> annotationClass) | 如果指定类型的注释存在于此元素上,则返回 true,否则返回 false。 |
boolean | isAnonymousClass() | 当且仅当底层类是匿名类时返回 true。 |
boolean | isArray() | 判定此 Class 对象是否表示一个数组类。 |
boolean | isAssignableFrom(Class<?> cls) | 判定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同,或是否是其超类或超接口。 |
boolean | isEnum() | 当且仅当该类声明为源代码中的枚举时返回 true。 |
boolean | isInstance(Object obj) | 判定指定的 Object 是否与此 Class 所表示的对象赋值兼容。 |
boolean | isInterface() | 判定指定的 Class 对象是否表示一个接口类型。 |
boolean | isLocalClass() | 当且仅当底层类是本地类时返回 true。 |
boolean | isMemberClass() | 当且仅当底层类是成员类时返回 true。 |
boolean | isPrimitive() | 判定指定的 Class 对象是否表示一个基本类型。 |
boolean | isSynthetic() | 如果此类是复合类,则返回 true,否则 false。有匿名类部类的类可以称作为复合类。 |
T | newInstance() | 调用默认构造方法创建此 Class 对象所表示的类的一个新实例。 |
String | toGenericString() | 返回该对象的描述,包含标识符等。 |
比较重要的方法:newInstance(),创建一个该类的实例,调用默认构造方法。
特殊的:
1、获取一个类声明时的确切泛型类型:
class Parameterized<T,V,Z>{
} Type classType = abstractTransfer.getClass().getGenericSuperclass();
Type[] ret = ((ParameterizedType)classType).getActualTypeArguments(); T = (Class) ret[0];
V = (Class) ret[1];
Z = (Class) ret[2];
2、运行时获取一个被代理的类的真实类对象
TrueClass proxyClass = proxy;
Class trueClass = proxyClass.getClass().getSuperclass();
二、ClassLoader对象
参考http://blog.chinaunix.net/uid-21227800-id-65879.html
类加载器是负责加载类的对象。ClassLoader 类是一个抽象类。如果给定类的二进制名称,那么类加载器会试图查找或生成构成类定义的数据。一般策略是将名称转换为某个文件名,然后从文件系统读取该名称的“类文件”。
每个 Class 对象都包含一个对定义它的 ClassLoader 的引用。
数组类的 Class 对象不是由类加载器创建的,而是由 Java 运行时根据需要自动创建。数组类的类加载器由 Class.getClassLoader() 返回,该加载器与其元素类型的类加载器是相同的;如果该元素类型是基本类型,则该数组类没有类加载器。
获取ClassLoader对象的几种方法:
1、通过Thread对象的getContextClassLoader()获取类加载器。一般为Thread.currentThread().getContextClassLoader()。 当前类的ClassLoader
2、通过Class对象的getClassLoader()方法获取类加载器。一般为this.getClass().getClassLoader()。 当前线程的ClassLoader
3、通过ClassLoader类的静态方法ClassLoader.getSystemClassLoader()方法。 系统ClassLoader,即系统的入口点所使用的ClassLoader。(注意,system ClassLoader与根ClassLoader并不一样。JVM下system ClassLoader通常为App ClassLoader)
这三个是否引用的同一对象呢?一般情况下是的,因为都返回True,其他高级应用中可能会不一样。
这个对象中还有很多操作资源的方法比较有用,自行查阅。
三、Package对象
Package 对象包含有关 Java 包的实现和规范的版本信息。通过用于加载类的 ClassLoader 实例,可以获取并获得此版本信息。通常,此信息存储在与类一起分发的清单中。
可以读Package的注解。
四、扫描一个包中的所有类
Java反射API研究(3)——java.lang.Class<T>的更多相关文章
- Java反射API研究(2)——java.lang.reflect详细内容与关系
对于最新的java1.8而言,reflect中接口的结构是这样的: java.lang.reflect.AnnotatedElement java.lang.reflect.AnnotatedType ...
- Java反射API研究(1)——注解Annotation
注解在表面上的意思,只是标记一下这一部分,最好的注解就是代码自身.而在java上,由于注解的特殊性,可以通过反射API获取,这种特性使得注解被广泛应用于各大框架,用于配置内容,代替xml文件配置. 要 ...
- Java反射API研究(4)——Class中的重要对象
一.Constructor与Method的父类:Executable Executable表示一个可执行类,构造方法与普通方法都是Executable AnnotatedType[] getAnnot ...
- JAVA反射系列之Field,java.lang.reflect.Field使用获取方法
JAVA反射系列之Field,java.lang.reflect.Field使用获取方法. 转载https://my.oschina.net/u/1407116/blog/209383 摘要 ja ...
- java和javax都是Java的API包,java是核心包,javax的x是extension的意思,也就是扩展包。
java和javax都是Java的API包,java是核心包,javax的x是extension的意思,也就是扩展包.
- 基于NACOS和JAVA反射机制动态更新JAVA静态常量非@Value注解
1.前言 项目中都会使用常量类文件, 这些值如果需要变动需要重新提交代码,或者基于@Value注解实现动态刷新, 如果常量太多也是很麻烦; 那么 能不能有更加简便的实现方式呢? 本文讲述的方式是, 一 ...
- Java反射API使用实例
/** * 访问Class对应的类所包含的注释:getAnnotation();getDelaredAnnotation(); * 访问Class对应的类所包含的内部类:getDecl ...
- Java反射api详解
虽然已经用了很多反射相关的api,但是还没有详细研究官方api文档,下面以1.6为基础研究一下api文档(因为只找到了1.6的中文版...),同时补充1.7和1.8对反射相关api的改变.
- java反射API
反射主要对象 Class Constructor Field Method API-Class 获取Class对象 Object.getClass() className.class Class.fo ...
随机推荐
- RDLC报表系列一
1.报表项目搭建: 配置好后,单击Web服务URL:http://lg-20151517ryre/ReportServer 如果电脑系统打开的时候没有设置密码的话,此时打开有可能会出现需要登录名和密码 ...
- mysql master or master copy
双主复制: 在两台server配置my.cnf [root@localhost mysql]# egrep -v "^$|^#" /etc/my.cnf datadir = /my ...
- 【ZZ】MySQL 索引优化全攻略 | 菜鸟教程
MySQL 索引优化全攻略 http://www.runoob.com/w3cnote/mysql-index.html
- VB.NET 指针
在.NET中,对指针指向数据的存储函数都封装在marshal类中,主要的函数包括:Copy.PtrToStringUni .PtrToStructure .OffsetOf.WriteXXX,Rrea ...
- es6 class 了解
ES6之class ES5中通常通过构造函数和原型的组合形式来创建对象.在ES6中引入class作为对象模板, Class定义语法 class point{ constructor(x,y){ thi ...
- Media Queries 媒体查询
1.什么是媒体查询 媒体查询可以让我们根据设备显示器的特性(如视口宽度.屏幕比例.设备方向:横向或纵向)为其设定CSS样式,媒体查询由媒体类型和一个或多个检测媒体特性的条件表达式组成.媒体查询中可用于 ...
- .net core 下的一个docker hello world
接触 docker 有段时间了,发现docker这个东西,真是越用越爽. 那就从零开始跑一个 docker simple . 方法一: 步骤一: dotnet new mvc --name myweb ...
- 外层div高度不随内层div高度改变的解决办法
当b1和b2都是float=left时候,a1层的高度不会被b1和b2的高度撑开. <div id=“div1″> <div id=”div2″ style="float: ...
- MongoDB中使用的SCRAM-SHA1认证机制
摘要: 介绍 SCRAM是密码学中的一种认证机制,全称Salted Challenge Response Authentication Mechanism. SCRAM适用于使用基于『用户名:密码』这 ...
- 在windows下安装python包管理器pip及使用
从来没有在Windows下用过pip,今天试了下,原来pip也可以在Windows下安装,使用也和Linux下一样简单. 先从下面的地址下载pip源码: http://pypi.python.or ...