百度百科中这样解释Java中的反射机制:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
我的理解:在java中程序两种状态为编译时状态和运行时状态,由于java语言高度抽象的特性,很多时候我们不通过实际的类的调用,通过实际类的父类就可以实现对子类成员的访问。反射是一种非常规的编程技术,一般用于设计系统框架等,然而在java中反射的作用有以下几个:
1.在运行时判断任意所属对象的类;
2.在运行时构造任意类的对象;
3.在运行时判断任意类所具有的的成员字段和方法;
4.在调用时调用任意对象的方法;
5.生成动态代理;
那么java是如何体现上面所说的各种特点呢?
Java中反射特点的体现主要依靠于一个类——Class<T>类,这个类比较特殊,他强烈体现了Java语言的封装特性,他获取对象的方法使用的就是反射机制,此处要说明的是Java中获得对象的几种方法:
(1)通过构造方法,使用new关键字;
(2)通过反射(字符串表示的类全名);
(3)通过克隆技术(clone),得到一个对象的副本,复制的对象和原对象都有自己的内存空间;
(4)通过反序列化,从文件读取对象;
Class 类的实例表示正在运行的 Java 应用程序中的类和接口。Class<T>类很少将T转化成一个真真的引用类型,多数情况下使用Calss<?>表示引用类型,其中“?”号是一个占位符,表示任意类型的类,然而在运行过程中他会自动解析为运行时的真真类类型,在Class<?>这个类型的对象中,封装了该类的所有元数据信息,例如:在Student类中,有name和age两个字段,分别用来表示姓名和年龄的信息,通过Class<?>类的引用可以访问?所代表的的任意类的成员段和成员方法及构造方法等,即该引用可以实现对所有类对象的数据的访问。那又该如何得到Class<?>类的对象?答案是,直接用名称加点得到;如对一个String类
则使用String.class就可以得到一个Class<?>的引用。值得注意的是Class<?>类字段成员都是以类的形式存在的,比如:
字段:Field类
方法:Method类
构造方法:Constructor类
参数:ParameterType类
修饰符:Modifier类
//...··类
所有引用类型的原数据,都会封装在属于它自己的Class对象中;
所有引用类型的构造方法信息,都会封装在属于它自己的Constructor对象中;
所有引用类型的方法信息,都会封装在属于它自己的Method对象中;
所有引用类型的字段信息,都会封装在属于它自己的Field对象中;
下面附上示例代码:
package com.cm; import java.lang.reflect.Constructor; import com.sun.util.Me; public class SimpleReflectTest { public static void main(String[] args) { // Class<String> c1 = String.class; // Me.println(c1); // String str = "how do you do?"; // Class<?> c2 = str.getClass(); // Me.println(c2); // c2 = String.class; // c2 = Integer.class; Class<?> c1 = String.class; Class<?> c2 = Integer.class; Class<?> c3 = Mo.class; Me.println(c1); Me.println(c2); Me.println(c3); Me.line(); Constructor<?>[] cs = c1.getConstructors(); for (Constructor<?> c : cs) { Me.println(c); } Me.line(); cs = c2.getConstructors(); for (Constructor<?> c : cs) { Me.println(c); } Me.line(); cs = c3.getConstructors(); cs = c3.getDeclaredConstructors(); for (Constructor<?> c : cs) { Me.println(c); } Me.line(); Class<?>[] css = new Class<?>[] { java.util.Date.class, java.sql.Date.class, Double.class }; for (Class<?> cl : css) { Constructor<?>[] cc = cl.getDeclaredConstructors(); for (Constructor<?> cons : cc) { Me.println(cons); } Me.println(); } } } class Mo { }
package com.sun.zone.gao; import java.lang.reflect.Constructor; import java.util.Set; import com.sun.util.Me; public class AbstractClassInterfaceTest { public static void main(String[] args) { Class<?> ca = Aaa.class; Constructor<?>[] cs = ca.getDeclaredConstructors(); for (Constructor<?> constructor : cs) { Me.println(constructor); } Me.println(); ca = Ia.class; Me.println(ca); cs = ca.getDeclaredConstructors(); for (Constructor<?> constructor : cs) { Me.println(constructor); } Me.line(); ca = AbstractClassInterfaceTest.class; cs = ca.getDeclaredConstructors(); for (Constructor<?> constructor : cs) { Me.println(constructor); } Me.println(); Aaa aaa = new Aaa() { @Override public void ma() { // TODO Auto-generated method stub } }; ca = aaa.go(); cs = ca.getDeclaredConstructors(); for (Constructor<?> constructor : cs) { Me.println("ok" + constructor); } Me.line(); ca = Sex.class; Me.println(ca); cs = ca.getDeclaredConstructors(); for (Constructor<?> constructor : cs) { Me.println(constructor); } } } enum Sex { Female, Male; private String name; Sex() { name = "女"; } Sex(String name) { this.name = name; } } interface Ia { int N = 100; void m1(); void m2(); } abstract class Aaa { // public Aaa() { // } // protected Aaa(String s) { // } public abstract void ma(); public void sayHello() { Me.println("hello,world!"); } private class Inner { } public Class<?> go() { return new Inner().getClass(); } }