Welcome 微信登录

首页 / 软件开发 / JAVA / Java反射机制:包括组成、结构和示例说明等内容

Java反射机制:包括组成、结构和示例说明等内容2014-08-03 cnblogs skywang12345

第1部分 Java 反射机制介绍

Java 反射机制。通俗来讲呢,就是在运行状态中,我们可以根据“类的部分已经的信息”来还原“类的全部的信息”。这里“类的部分已经的信息”,可以是“类名”或“类的对象”等信息。“类的全部信息”就是指“类的属性,方法,继承关系和Annotation注解”等内容。

举个简单的例子:假设对于类ReflectionTest.java,我们知道的唯一信息是它的类名是“com.skywang.Reflection”。这时,我们想要知道ReflectionTest.java的其它信息(比如它的构造函数,它的成员变量等等),要怎么办呢?
这就需要用到“反射”。通过反射,我们可以解析出ReflectionTest.java的完整信息,包括它的构造函数,成员变量,继承关系等等。

在了解了“java 反射机制”的概念之后,接下来思考一个问题:如何根据类的类名,来获取类的完整信息呢?

这个过程主要分为两步:
第1步:根据“类名”来获取对应类的Class对象。
第2步:通过Class对象的函数接口,来读取“类的构造函数,成员变量”等信息。
下面,我们根据示例来加深对这个概念的理解。示例如下(Demo1.java):

package com.skywang.test; import java.lang.Class; public class Demo1 { public static void main(String[] args) { try {// 根据“类名”获取 对应的Class对象Class<?> cls = Class.forName("com.skywang.test.Person"); // 新建对象。newInstance()会调用类不带参数的构造函数Object obj = cls.newInstance(); System.out.println("cls="+cls);} catch (Exception e) {e.printStackTrace();}}} class Person {public Person() {System.out.println("create Person");}}
运行结果:
create Person
cls=class com.skywang.test.Person

说明:
(01) Person类的完整包名是"com.skywang.test.Person"。而 Class.forName("com.skywang.test.Person"); 这一句的作用是,就是根据Person的包名来获取Person的Class对象。
(02) 接着,我们调用Class对象的newInstance()方法,创建Person对象。

现在,我们知道了“java反射机制”的概念以及它的原理。有了这个总体思想之后,接下来,我们可以开始对反射进行深入研究了。

第2部分 Class 详细说明

1 获取Class对象的方法

我这里总结了4种常用的“获取Class对象”的方法:
方法1:Class.forName("类名字符串") (注意:类名字符串必须是全称,包名+类名)
方法2:类名.class
方法3:实例对象.getClass()
方法4:"类名字符串".getClass()

下面,我们通过示例演示这4种方法。示例如下(Demo2.java):

package com.skywang.test; import java.lang.Class; public class Demo2 { public static void main(String[] args) { try {// 方法1:Class.forName("类名字符串")(注意:类名字符串必须是全称,包名+类名)//Class cls1 = Class.forName("com.skywang.test.Person");Class<?> cls1 = Class.forName("com.skywang.test.Person");//Class<Person> cls1 = Class.forName("com.skywang.test.Person"); // 方法2:类名.classClass cls2 = Person.class;// 方法3:实例对象.getClass()Person person = new Person();Class cls3 = person.getClass(); // 方法4:"类名字符串".getClass()String str = "com.skywang.test.Person"; Class cls4 = str.getClass(); System.out.printf("cls1=%s, cls2=%s, cls3=%s, cls4=%s
", cls1, cls2, cls3, cls4); } catch (Exception e) {e.printStackTrace();}}} class Person {public Person() {System.out.println("create Person");}}
运行结果:

create Person
cls1=class com.skywang.test.Person, cls2=class com.skywang.test.Person, cls3=class com.skywang.test.Person, cls4=class java.lang.String

2 Class的API说明

Class的全部API如下表:

Class的全部API如下表:public static ClassforName(String className)public static ClassforName(String name, boolean initialize, ClassLoader loader)public ConstructorgetConstructor(Class[] parameterTypes)public Constructor[]getConstructors()public ConstructorgetDeclaredConstructor(Class[] parameterTypes)public Constructor[]getDeclaredConstructors()public ConstructorgetEnclosingConstructor()public MethodgetMethod(String name, Class[] parameterTypes)public Method[]getMethods()public MethodgetDeclaredMethod(String name, Class[] parameterTypes)public Method[]getDeclaredMethods()public MethodgetEnclosingMethod()public FieldgetField(String name)public Field[]getFields()public FieldgetDeclaredField(String name)public Field[]getDeclaredFields()public Type[]getGenericInterfaces()public TypegetGenericSuperclass()public Annotation<A>getAnnotation(Class annotationClass)public Annotation[]getAnnotations()public Annotation[]getDeclaredAnnotations()public booleanisAnnotation()public booleanisAnnotationPresent(Class annotationClass)public booleanisAnonymousClass()public booleanisArray()public booleanisAssignableFrom(Class cls)public booleandesiredAssertionStatus()public Class<U>asSubclass(Class clazz)public ClassgetSuperclass()public ClassgetComponentType()public ClassgetDeclaringClass()public ClassgetEnclosingClass()public Class[]getClasses()public Class[]getDeclaredClasses()public Class[]getInterfaces()public booleanisEnum()public booleanisInstance(Object obj)public booleanisInterface()public booleanisLocalClass()public booleanisMemberClass()public booleanisPrimitive()public booleanisSynthetic()public StringgetSimpleName()public StringgetName()public StringgetCanonicalName()public StringtoString()public ClassLoadergetClassLoader()public PackagegetPackage()public intgetModifiers()public ProtectionDomaingetProtectionDomain()public URLgetResource(String name)public InputStreamgetResourceAsStream(String name)public Objectcast(Object obj)public ObjectnewInstance()public Object[]getSigners()public Object[]getEnumConstants()public TypeVariable[]getTypeParameters()
我们根据类的特性,将Class中的类分为4部分进行说明:构造函数,成员方法,成员变量,类的其它信息(如注解、包名、类名、继承关系等等)。Class中涉及到Annotation(注解)的相关API,可以点击查看前一章节关于Annotation的详细介绍。