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

Java反射学习-使用反射修改一个类中的所有String类型的成员变量的值

2016-05-23 00:56 645 查看
这个是我在学习java反射技术时的一个小Demo,理解了它你说你不会java反射,人家都不相信。

下面的这个类是一个JavaBean,我们要做的事情修改JaveBean中所有的String类型的成员变量的值,将’b’修改为’a’:

package com.mari.reflect;

/**
* @author sync
*
*/
public class ReflectPoint {

public String str1 = "ball";
private String str2 = "basketball";
private String str3 = "adflash";

private int x;
private int y;

public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ReflectPoint other = (ReflectPoint) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}

public int getX() {
return x;
}

public void setX(int x) {
this.x = x;
}

public int getY() {
return y;
}

public void setY(int y) {
this.y = y;
}

@Override
public String toString() {
return "ReflectPoint [str1=" + str1 + ", str2=" + str2 + ", str3=" + str3 + "]";
}

}


下面这个是测试类:

package com.mari.reflect;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

public class Main {

public static void main(String[] args) throws Exception {

//测试修改String类型成员变量的值
ReflectPoint reflectPoint = new ReflectPoint(3, 5);
System.out.println(reflectPoint);
changeStringValue(reflectPoint);
System.out.println(reflectPoint);

System.out.println("=====================================");

//调用main函数时,需要将数组转化成为Object对象
Method methodMain = TestArgument.class.getMethod("main", String[].class);
methodMain.invoke(null, (Object) new String[]{"123", "321", "abc"});

System.out.println("=====================================");

//测试class.isArray, Array.get
String[] a1 = new String[]{"a","b","c","d"};
int[] a2 = new int[]{1,2,3,4};
String s1 = "aaaaaaaaaa";
printObject(a1);
printObject(a2);
printObject(s1);
}

//判断传递过来的参数是否是Array类型,这里也说明了在java中同一个类型的字节码文件只会在内存中加载一次.
//通过查看源码也可以发现在每次加载时会先判断缓存的CacheClass是否存在.存在就返回CacheClass.不存在才
//会去加载Class
private static void printObject(Object obj){
Class<?> cls = obj.getClass();
if (cls.isArray()) {
int len = Array.getLength(obj);
for (int i = 0; i < len; i++) {
System.out.println(Array.get(obj, i));
}
} else {
System.out.println(obj);
}
}

//使用反射技术动态修改String类型的成员变量的值.
private static void changeStringValue(Object obj) throws Exception {
Field[] fields = obj.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.getType() == String.class) {
field.setAccessible(true);
String oldValue = (String) field.get(obj);
String newValue = oldValue.replace('b', 'a');
field.set(obj, newValue);
}
}
}

}

//测试main函数的类,反射调用mian函数时参数不能直接传入数组类型,需要转换成Object类型才能正常调用.
//这个原因可能是和java的自动装箱拆箱或者可变参数类型有关系吧
//具体的我也不清楚了,有哪位读者清楚的话,欢迎留言.
class TestArgument {

public static void main(String[] args) {
for (String string : args) {
System.out.println(string);
}
}

}


下面是测试类的输出结果:

ReflectPoint [str1=ball, str2=basketball, str3=adflash]
ReflectPoint [str1=aall, str2=aasketaall, str3=adflash]
=====================================
123
321
abc
=====================================
a
b
c
d
1
2
3
4
aaaaaaaaaa
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: