此文章的例题和思想来源于:张孝祥高新技术。
反射中有一个十分重要的词:字节码。得到字节码实际上就是.getClass()。比如一个String对象str,str.getClass()得到的就是str所属类String的字节码。对于每个类字节码是独一无二的,所以判断类之间是否相同时不用equal而直接用==即可。
下面贴一段代码,这段代码处理的内容是得到一个类中一个变量的值,并且将此类中String类变量的值中的所有字符b改成a。
package junitTest;
import java.lang.reflect.Field;
public class ReflectTest {
public static void main(String[] args) throws Exception {
StringTest st = new StringTest(3,4);
Field str1 = st.getClass().getDeclaredField("a");//通过st的字节码得到名为a的字段
str1.setAccessible(true);//设置a为可见
System.out.println(str1.getName()+"="+str1.get(st));//返回a在对象st上的值,即得到3
changeTheString(st);
System.out.println(st);
}
public static void changeTheString(Object obj) throws Exception {//将String类变量的所有字母b改为a
Field[] fields = obj.getClass().getDeclaredFields();
for(Field field : fields){
if(field.getType() == String.class){//如果字节码相等,即都是String类
field.setAccessible(true);//全部String变量设置为可见
String s1 = (String)field.get(obj);//返回值由Object改为String
System.out.println("改前"+s1);
String s2 = s1.replace("b", "a");//将String类变量的所有字母b改为a
System.out.println("改后"+s2);
field.set(obj, s2);//真正改变值
}
}
}
}
class StringTest{
String string1 = "aabbcc";
private String string2 = "bababa";
String string3 = "b will be turned into a";
private int a;
private int b;
public StringTest(int a, int b) {
super();
this.a = a;
this.b = b;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return string1+" "+string2+" "+string3;
}
}
其中我发现Field的get和set方法是很需要重视的,Field对象.get(某个对象),是指得到“Field对象”所指变量在“某个对象”中的值。