您的位置:首页 > 编程语言 > Java开发

Java反射机制小结

2015-06-21 14:49 405 查看
要了解Java反射机制,前提是搞清楚Class类(Class类型)怎么理解?翻阅了一些资料,Class类(Class类型)是定义Java程序中一个特定类的实现,Class类(Class类型)的对象(实例)用于表示当前运行的Java应用程序中的类和接口。

举个栗子,张三、李四等,可以用Person来描述

class Person{
//张三和李四共同具备的行为和状态
}


Person就是张三、李四(是Person的对象)的类型,引申出Date、String类又是什么类型呢?Class类型。二者作为对比:

Person类代表人,它的实例对象就是张三、李四这样一个个具体的人

Class类代表Java类,它的实例对象对应各个类在内存中(JVM中)的字节码。例如,Person类的字节码,ArrayList类的字节码,等等。一个类被类加载器加载到内存中,占用一片存储空间。这个空间里面的内容就是类的字节码。不同的类的字节码是不同的,所以它们在内存中的内容是不同的。一个类在虚拟机中只有一份字节码。

问题1:Class类的实例到底表示的是哪一份字节码,为了明确区分出Class类的实例表示的是谁的字节码,Class类提供了泛型

Class<Date> clz1 = Date.class; //clz1表示Date的字节码

Class<String> clz2 = String.class; //clz2表示String的字节码

问题2:如何得到Class类的实例,有三种方式,其中2、3用的较多

1.类名.class(就是一份字节码);

2.Class.forName(String className);//根据一个类的全限定名来构建Class对象,那么就能得到这个类的父类、属性、方法等

3.每一个对象都有getClass()方法: obj.getClass(); 返回对象的真实类型,即编译类型,突然间想起某人和我说的一句话,“编译时决定类型,运行时绑定对象”,哈哈^^

package test.cd;

/**
* @author quyang.ybb
*
*/
public class User {

}


package test.cd.clazz;

import test.cd.User;

/**
* @author quyang.ybb
*
*/
public class ClassInstanceDemo {
public static void main(String[] args) throws Exception {
// 第一种方式:类名.class;
Class<User> clz1 = User.class;
System.out.println(clz1);

// 第二种方式:Class.forName(String className);
// 用?表示是因为后面是字符串,clz2并不知道自己表示的是谁
Class<?> clz2 = Class.forName("test.cd.User");
System.out.println(clz2);

// 第三种方式:对象.getClass();
User user = new User();
Class clz3 = (Class) user.getClass();
System.out.println(clz3);

System.out.println("clz1 == clz2 : " + (clz1 == clz2));
System.out.println("clz1 == clz3 : " + (clz1 == clz3));
System.out.println("clz2 == clz3 : " + (clz2 == clz3));

User user11 = new User();
Class clz11 = user11.getClass();
User user22 = new User();
Class clz22 = user22.getClass();
System.out.println(clz11==clz22);
System.out.println(clz11.getClassLoader());
System.out.println(clz22.getClassLoader());
}
}


打印结果:

class test.cd.User

class test.cd.User

class test.cd.User

clz1 == clz2 : true

clz1 == clz3 : true

clz2 == clz3 : true

true

sun.misc.Launcher$AppClassLoader@53004901

sun.misc.Launcher$AppClassLoader@53004901

从打印结果可知,一个类在JVM中只有一份字节码(User.class)。

问题3:如果我想获取某一个类中所有的构造器(当然也可以是类中所有的属性或方法等)呢?应该怎么做?

1.明确知道操作的是哪一份字节码对象,即哪个Class类的实例

2.获取构造器

在实践过程中发现会涉及Constructor类:表示类中构造器的类型,Constructor的实例就是某一个类中的某一个构造器,此外还有Method类,Field类,分别表示类中方法的类型和字段的类型,Method的实例就是某一个类中的某一个方法,Field的实例就是某一个类中的某一个字段。

问题4:请用图形象画出Class类的实例在内存中的情况

我们可以把每个Class类的对象当做众多类的代理。而且在每个Class类对象中都会有字段记录他引用的这个类的类加载器。java中有多个加载器,每个加载器能载入多个类,所以只要取得Class类对象,就可利用其getClassLoader()方法取得该类加载器的引用。JVM为每种类管理着独一的Class对象。因此我们可以用双等号操作符来比较对象:a1.getClass()==A.class;应该返回的是true。





问题5:Class类中都有一些什么方法?

getClassLoader()
//获取该类的类装载器。
getComponentType()
//如果当前类表示一个数组,则返回表示该数组组件的 Class 对象,否则返回 null。
getConstructor(Class[])
//返回当前 Class 对象表示的类的指定的公有构造子对象。
getConstructors()
//返回当前 Class 对象表示的类的所有公有构造子对象数组。
getDeclaredConstructor(Class[])
//返回当前 Class 对象表示的类的指定已说明的一个构造子对象。
getDeclaredConstructors()
//返回当前 Class 对象表示的类的所有已说明的构造子对象数组。
getDeclaredField(String)
//返回当前 Class 对象表示的类或接口的指定已说明的一个域对象。
getDeclaredFields()
//返回当前 Class 对象表示的类或接口的所有已说明的域对象数组。
getDeclaredMethod(String, Class[])
//返回当前 Class 对象表示的类或接口的指定已说明的一个方法对象。
getDeclaredMethods()
//返回 Class 对象表示的类或接口的所有已说明的方法数组。
getField(String)
//返回当前 Class 对象表示的类或接口的指定的公有成员域对象。
getFields()
//返回当前 Class 对象表示的类或接口的所有可访问的公有域对象数组。
getInterfaces()
//返回当前对象表示的类或接口实现的接口。
getMethod(String, Class[])
//返回当前 Class 对象表示的类或接口的指定的公有成员方法对象。
getMethods()
//返回当前 Class 对象表示的类或接口的所有公有成员方法对象数组,包括已声明的和从父类继承的方法。
getModifiers()
//返回该类或接口的 Java 语言修改器代码。
getName()
//返回 Class 对象表示的类型(类、接口、数组或基类型)的完整路径名字符串。
getResource(String)
//按指定名查找资源。
getResourceAsStream(String)
//用给定名查找资源。
getSigners()
//获取类标记。
getSuperclass()
//如果此对象表示除 Object 外的任一类, 那么返回此对象的父类对象。
isArray()
//如果 Class 对象表示一个数组则返回 true, 否则返回 false。
isAssignableFrom(Class)
//判定 Class 对象表示的类或接口是否同参数指定的 Class 表示的类或接口相同,或是其父类。
isInstance(Object)
//此方法是 Java 语言 instanceof 操作的动态等价方法。
isInterface()
//判定指定的 Class 对象是否表示一个接口类型。
isPrimitive()
//判定指定的 Class 对象是否表示一个 Java 的基类型。
newInstance()
//创建类的新实例。
toString()
//将对象转换为字符串。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: