1. 程式人生 > >Java反射-使用反射修改一個類中的所有String型別的成員變數的值

Java反射-使用反射修改一個類中的所有String型別的成員變數的值

這個是我在學習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