文章目录
(一)
1.概念
反射就是把Java的各种成分映射成相应的Java类。
Class类的构造方法是private,由JVM创建。
反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作。例如它允许一个java的类获取他所有的成员变量和方法并且显示出来。Java 的这一能力在实际应用中也许用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性。例如,Pascal、C 或者 C++ 中就没有办法在程序中获得函数定义相关的信息。 (来自Sun)
JavaBean 是 reflection 的实际应用之一,它能让一些工具可视化的操作软件组件。这些工具通过 reflection 动态的载入并取得 Java 组件(类) 的属性。
反射是从1.2就有的,后面的三大框架都会用到反射机制,涉及到类”Class”,无法直接new CLass(),其对象是内存里的一份字节码.
Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。
2.三种获取Class的方法
package com.forName03;
public class Test01 {
public static void main(String[] args) throws ClassNotFoundException {
person p = new person();
//1、通过对象调用 getClass() 方法来获取,通常应用在:比如你传过来一个 Object
// 类型的对象,而我不知道你具体是什么类,用这种方法
Class c1 = p.getClass();
//2、直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高
// 这说明任何一个类都有一个隐含的静态成员变量 class
Class c2 = person.class;
//3、通过 Class 对象的 forName() 静态方法来获取,用的最多,
// 但可能抛出 ClassNotFoundException 异常
Class c3 = Class.forName("com.forName03.person");
System.out.println(c1);//class com.forName03.person
System.out.println(c2);//class com.forName03.person
System.out.println(c3);//class com.forName03.person
}
}
3.reflection 工作示例
public static void main(String args[]) {
try {
Class c = Class.forName("java.util.Stack");
Method m[] = c.getDeclaredMethods();
for (int i = 0; i < m.length; i++)
System.out.println(m[i].toString());
} catch (Throwable e){
System.err.println(e);
}
}
}
/*
public synchronized java.lang.Object java.util.Stack.pop()
public java.lang.Object java.util.Stack.push(java.lang.Object)
public boolean java.util.Stack.empty()
public synchronized java.lang.Object java.util.Stack.peek()
public synchronized int java.util.Stack.search(java.lang.Object)*/
4.显示对象类名
package com.forName;
public class Test03 {
//显示对象的类名
public static void main(String[] args) {
person p =new person();
printClassName(p);
System.out.println("The name of class person is: "+person.class.getName());
}
static void printClassName(Object obj) {
System.out.println("The class of " + obj + " is " + obj.getClass().getName());
}
//The class of com.forName.person@1b6d3586 is com.forName.person
//The name of class person is: com.forName.person
}
(二)例题
1.将所有String类型的成员变量里的b改成a
package com.forName.example;
import java.lang.reflect.Field;
public class theString {
public static void main(String[] args) throws SecurityException, NoSuchMethodException, NoSuchFieldException, IllegalArgumentException, Exception {
ReflectPointer rp1 = new ReflectPointer(3,4);
changeBtoA(rp1);
System.out.println(rp1);
}
private static void changeBtoA(Object obj) throws RuntimeException, Exception {
Field[] fields = obj.getClass().getFields();
for(Field field : fields) {
//if(field.getType().equals(String.class))
// 由于字节码只有一份,用equals语义不准确
if(field.getType()==String.class) {
String oldValue = (String)field.get(obj);
String newValue = oldValue.replace('b', 'a');
field.set(obj,newValue);//设新值
}
}
}
}
class ReflectPointer {
private int x = 0;
public int y = 0;
public String str1 = "ball";
public String str2 = "basketball";
public String str3 = "itcat";
public ReflectPointer(int x,int y) {
//alt + shift +s相当于右键source super();
// TODO Auto-generated constructor stub
this.x = x; this.y = y;
}
@Override public String toString() {
return "ReflectPointer [str1=" + str1 + ", str2=" + str2 + ", str3=" + str3 + "]";
}
}
/*输出结果
* test{a=1, b=3}
* */
2.模拟 instanceof 操作符
package com.forName.example;
public class instanceofTest {
public static void main(String args[]) {
try {
Class cls = Class.forName("com.forName.example.S");
boolean b1 = cls.isInstance(new Integer(37));
System.out.println(b1);
boolean b2 = cls.isInstance(new S());
System.out.println(b2);
} catch (Throwable e) {
System.err.println(e);
}
}
//false
//true
}
class S {
}
在这个例子中创建了一个S 类的 Class 对象,然后检查一些对象是否是S的实例。new Integer(37) 不是,但 new S()是。