Java反射-使用反射修改一個類中的所有String型別的成員變數的值
阿新 • • 發佈:2019-02-18
這個是我在學習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