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

你可能感兴趣的:(Java)