Class对象其实就是用来创建所有类的所有的“常规”对象的。java使用Class对象来执行其RTTI(运行时识别类和对象的信息),即使你正在执行的是类似转型这样的操作。
类是程序的一部分,每个类都有一个Class对象,换个说法就是每当编写了一个新类的时候,就会产生一个Class对象。为了生成这个类的对象,运行这个程序的java虚拟机(JVM)将使用“类加载器”的子系统。
类加载器子系统实际上可以包含一条类加载器链,但是只有一个原生类加载器,它是JVM实现的一部分。原生类加载器加载的是所谓的可信类,包括java API类,它们通常是从本地盘加载。在这条链中,通常不需要添加额外的类加载器,但是如果你有特殊需求(例如以某种特殊的方式加载类,以支持Web服务器应用,或者在网络中下载类),那么你有一种方式可以挂接额外的类加载器。
所有的类都是在对其第一次使用时,动态加载到JVM中的,当程序 创建一个对类的静态成员的引用时,就会加载这个类。这个证明构造器也是类的静态方法,即使在构造器之前并没有使用static关键字,因此,使用new操作符创建类的新对象也会被当作对类的静态成员的引用。
因此,java程序在他开始运行之前并非完全被加载,其各个部分是在必需时才加载的。
类加载器首先检查这个类的Class对象是否已经加载。如果尚未加载,默认的类加载器就会根据类名查找.class文件(例如,某个附加类加载器可能会在数据库中查找字节码)。在这个类的字节码被加载时,它们会接受验证,以确保没有被破坏。并且不包含不良的java代码。
一旦某个类的Class对象被载入内存中,它就被用来创建这个类的所有对象
Class.forName(“类名”)可以根据提供的类名而取得操作此类对象的引用。如果此方法没有找到你所写的类名,那么他就会抛出一个异常 ClassNotFoundException,无论什么时候,只要你想在运行时使用类型信息,就必须首先获得对恰当的Class对象的引用。Class.forName(“类名”)就是实现此功能的便捷途径,因为你不需要为了获得Class引用而持有该类型的对象。但是如果你已经有个该对象(例如你已经new了你想要的对象),那么就可以此对象调用getClass方法来获取Class引用。这个方法属于根类Object的一部分,它将返回表示该对象的实际类型的Class引用。
通过Class对象可以在运行时发现一个对象完整的类继承结构
调用运行时类本身的class属性(不需要实例化对象):
例如 Class s=String,class
调用Class.forName()方法(不需要实例化对象):只需要在里面传入所需得到class对象的全路径名即可
例如:Class
java还提供了另外一种方法来生成对Class对象的引用,即使用类字面常亮,语法如下 类名.class
类字面常量不仅可以应用于普通的类,也可以应用于接口,数组以及基本数据类型。
当使用“.class”来创建对Class对象的引用时,不会自动的初始化该Class对象。为了使用类而做的准备工作有下面三个步骤:
Class引用总是指向某个Class对象,它可以制造类的实例,并包含可作用这些实例的所有方法代码.它还包含该类的静态成员,因此,Class引用表示的就是他所指向的对象的确切类型,而该对象便是Class类的一个对象
一次java SE5的设计者看准机会,将它的类型变得更加具体,而这是通过允许你对Class引用所指向的Class对象的类型进行限定而实现的,这里用到了泛型语法,即可以在Class<限定>这样来加泛型以限定想要的Class引用.
注意:当使用Class.newInstance()获得实例对象的时候,此对象必须要有一个默认的构造器,不然会报异常
当将泛型语法用于Class对象的时候:newInstance()将返回该对象的确切信息,而不仅仅是Object,但是如果你手头上是此对象的超类Class对象,那么如果你调用此超类Class的newInstance()方法那么只能用Object对象接收
目前我们已知的运行时识别类的类型信息以下三种:
主要是指程序可以访问、检测和修改它本身状态或行为的一种能力.重要的是,我们要认识到反射并没有什么神奇的地方,当通过反射与一个未知类型的对象打交道的时候,JVM知识简单的检查这个对象,看它属于哪个特定的类(就像RTTI一样).在用它做其他事情之前必须先加载哪个类的Class对象.因此,哪个类的.class文件对于JVM来说必须是可获取的:即要么在本地机器上,要么可以通过网络取得所以RTTI和反射之间真正的区别,对RTTI来说,编译器在编译时打开和检查.class文件(换句话说,我们可以用普通方式调用对象的所有方法).但是对于反射来说.class文件在编译时是不可获取的.所以在运行时打开和检查.class文件
Class类和java.lang.reflect类库一起对反射的概念进行了支持,该类库包含了Field,Method以及Constructor类(每个类都实现了Member接口).这些类型的对象是由JVM在运行时创建的,用以表示未知类里所对应的成员信息.这样就可以用Constructor创建新的对象,用哪个get()和set()方法读取和修改Field对象关联的字段,用invoke()方法调用与Method对象关联的方法,另外,还可以调用getFields(),getMethods()和getConstructors()等很便利的方法,以返回表示字段,方法以及构造器的对象的数组
如果类中有属性的话,两个方法都是返回一个Field数组.其中getDeclaredFields()方法返回的是所有参数包括public, protected, default,private.而getFields()只返回public的参数. getMethods(), getConstructors()都是一样的
有下面一个domain类,可以通过反射将他的所有属性信息,方法信息以及构造器的信息在运行时给读取出来
/**
* @description TBapInterParadomain
* @author [email protected]
* @date 20180301 15:47:23
* @review [email protected]/2018-03-01
*/
public class TBapInterPara{
/**
* UUID
*/
private String uuid;
/**
* 字段名称
*/
private String fieldNm;
/**
* 字段类型
*/
private String fieldTyp;
/**
* 是否要求输入
*/
private String required;
/**
* 备注
*/
private String remarks;
/**
* 等级
*/
private String levelPara;
/**
* 信息表UUID
*/
private String infoUuid;
private ParameVo parameVo;
private List parameVos;
public TBapInterPara() {
super();
}
/**
* get UUID
*/
public String getUuid() {
return uuid;
}
/**
* set UUID
*/
public void setUuid(String uuid) {
this.uuid = uuid;
}
/**
* get 字段名称
*/
public String getFieldNm() {
return fieldNm;
}
/**
* set 字段名称
*/
public void setFieldNm(String fieldNm) {
this.fieldNm = fieldNm;
}
/**
* get 字段类型
*/
public String getFieldTyp() {
return fieldTyp;
}
/**
* set 字段类型
*/
public void setFieldTyp(String fieldTyp) {
this.fieldTyp = fieldTyp;
}
/**
* get 是否要求输入
*/
public String getRequired() {
return required;
}
/**
* set 是否要求输入
*/
public void setRequired(String required) {
this.required = required;
}
/**
* get 备注
*/
public String getRemarks() {
return remarks;
}
/**
* set 备注
*/
public void setRemarks(String remarks) {
this.remarks = remarks;
}
/**
* get 等级
*/
public String getLevelPara() {
return levelPara;
}
/**
* set 等级
*/
public void setLevelPara(String levelPara) {
this.levelPara = levelPara;
}
/**
* get 信息表UUID
*/
public String getInfoUuid() {
return infoUuid;
}
/**
* set 信息表UUID
*/
public void setInfoUuid(String infoUuid) {
this.infoUuid = infoUuid;
}
}
/**
* @program: demo
* @description: 反射
* @author: [email protected]
* @create: 2018-03-29 16:02
**/
public class Demo11 {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
Class tBapInterParaClass=TBapInterPara.class;
Field[] fields = tBapInterParaClass.getDeclaredFields();//获得所有的字段,包括private的
Method[] methods = tBapInterParaClass.getMethods();
tBapInterParaClass.getDeclaredMethods();
Constructor>[] constructors = tBapInterParaClass.getConstructors();
for (int i = 0; i < fields.length; i++) {
System.out.println(fields[i].getType());
System.out.println(fields[i].getName());
System.out.println("-----------------");
}
System.out.println("methods:");
for (int k = 0; k < methods.length; k++) {
System.out.println(methods[k].getName());
System.out.println("-----------------");
}
System.out.println("constructors:");
for (int j = 0; j < constructors.length; j++) {
System.out.println(constructors[j]);
}
}
}
运行结果
class java.lang.String
uuid
-----------------
class java.lang.String
fieldNm
-----------------
class java.lang.String
fieldTyp
-----------------
class java.lang.String
required
-----------------
class java.lang.String
remarks
-----------------
class java.lang.String
levelPara
-----------------
class java.lang.String
infoUuid
-----------------
class tese2.ParameVo
parameVo
-----------------
interface java.util.List
parameVos
-----------------
methods:
getUuid
-----------------
setUuid
-----------------
getFieldNm
-----------------
setFieldNm
-----------------
getFieldTyp
-----------------
setFieldTyp
-----------------
getRequired
-----------------
setRequired
-----------------
getRemarks
-----------------
setRemarks
-----------------
getLevelPara
-----------------
setLevelPara
-----------------
getInfoUuid
-----------------
setInfoUuid
-----------------
wait
-----------------
wait
-----------------
wait
-----------------
equals
-----------------
toString
-----------------
hashCode
-----------------
getClass
-----------------
notify
-----------------
notifyAll
-----------------
constructors:
public tese2.TBapInterPara()