/** * 反射(构造方法,成员变量,普通方法,数组) * * @author 张明学 * */ public class ReflectStudy { @SuppressWarnings("unused") public static void main(String[] args) throws Exception {
System.out.println("--------1. 构造方法反射-------"); Class strClass = String.class; Constructor[] constr = strClass.getConstructors(); // String的所有构造方法 for (Constructor constructor : constr) { System.out.println("构造方法参数个数:" + constructor.getParameterTypes().length); for (Class c : constructor.getParameterTypes()) { System.out.print(c.getName() + "\t"); } System.out.println(); } // 获取构造方法 Constructor constructor = String.class.getConstructor(StringBuffer.class); String str1 = (String) constructor.newInstance(new StringBuffer("abc")); System.out.println(str1.charAt(1)); // Class对象的newInstance()方法是对无参的构造方法的调用 String s1 = String.class.newInstance(); String s2 = new String(); System.out.println(s1.toString()); System.out.println(s2.toString());
输出结果:
--------1. 构造方法反射------- 构造方法参数个数:3 [C int int 构造方法参数个数:3 [I int int 构造方法参数个数:4 [B int int int 构造方法参数个数:2 [B int 构造方法参数个数:1 [C 构造方法参数个数:1 java.lang.String 构造方法参数个数:2 [B java.lang.String 构造方法参数个数:3 [B int int 构造方法参数个数:1 [B 构造方法参数个数:1 java.lang.StringBuffer 构造方法参数个数:1 java.lang.StringBuilder 构造方法参数个数:4 [B int int java.lang.String 构造方法参数个数:0 b
System.out.println("--------2. 成员变量反射-------"); // 获得成员变量(注:成员变量属于Class所有不属于某个对象) // public类型的可以直接获取 Field filedX = Point.class.getField("x"); // private类型的要通用getDeclaredField()方法获取 Field filedY = Point.class.getDeclaredField("y"); Point p = new Point(3, 7); // 获取成员变量的值(必须属于某个对象) System.out.println(filedX.get(p));// public类型可以直接获取 // private类型要设置setAccessible(true)才能获取变量值 filedY.setAccessible(true); System.out.println(filedY.get(p)); System.out.println(p); changeStringValue(p); System.out.println(p);
--------2. 成员变量反射------- 3 7 Point对象的值:str1 = abc str2 = abcabc str3 = ac Point对象的值:str1 = Bbc str2 = BbcBbc str3 = Bc
System.out.println("--------3. 方法反射-------"); // Method也是属于Class所有 Method charAtMethod = String.class.getMethod("charAt", int.class); // Method的调用必须属于某个对象:invoke(对象,参数...) // invoke(null, 参数...)表示调用的静态方法 String s = new String("abc"); System.out.println(charAtMethod.invoke(s, 2)); // 静态调用 TestArguments.main(new String[] { "111", "222", "333" }); // 类名由main(String[] args)方法中的第一个参数指定 if (args.length > 0) { String startingClassName = args[0]; Method startdMainMethod = Class.forName(startingClassName) .getMethod("main", String[].class); // main为静态方法 startdMainMethod.invoke(null, (Object) new String[] { "aaa", "bbb", "ccc" }); // 或 startdMainMethod.invoke(null, new Object[] { new String[] { "aaa", "bbb", "ccc" } }); }
--------3. 方法反射------- c 111 222 333 aaa bbb ccc aaa bbb ccc
System.out.println("--------4. 数组反射-------"); int[] a1 = new int[3]; int[] a2 = new int[6]; int[][] a3 = new int[3][3]; String[] a4 = new String[3]; // ******数组的反射:维数和类型相同的数组的Class是相同的****** \\ System.out.println(a1.getClass() == a2.getClass());// true System.out.println(a1.getClass() == a3.getClass());// true System.out.println(a1.getClass() == a4.getClass());// true // 数组可以转换成Object Object o1 = a1; Object o2 = a3; Object o3 = a4; // 基本数据类型的数组不能转换成Object[],复杂数据类型的数组可以转换成Object[] // Object[] o4 = a1; Object[] o5 = a3; Object[] o6 = a4; // Arrays工具类 a1 = new int[] { 1, 2, 3 }; a4 = new String[] { "a", "b", "c" }; System.out.println(Arrays.asList(a1));// 显示:[[I@9cab16] System.out.println(Arrays.asList(a4));// 显示:[a, b, c] printObject(a4); printObject("abc"); }
--------4. 数组反射------- true false false [[I@9cab16] [a, b, c] a b c abc
private static void printObject(Object obj) { Class clazz = obj.getClass(); if (clazz.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类型成员变量的属性值(将a换成B) * * @param p * @throws * @throws Exception */ private static void changeStringValue(Point p) throws Exception { Field[] fileds = p.getClass().getDeclaredFields(); for (Field field : fileds) { // 任何类型的Class只有一份 if (field.getType() == String.class) { String filedValue = (String) field.get(p); String newValue = filedValue.replace("a", "B"); field.set(p, newValue); } } } } class TestArguments { public static void main(String[] args) { for (String arg : args) { System.out.println(arg); } } }
所用的Point类如下:
public class Point { public int x; private int y; public String str1 = "abc"; public String str2 = "abcabc"; public String str3 = "ac"; public Point(int x, int y) { this.x = x; this.y = y; } @Override public String toString() { return "Point对象的值:str1 = " + str1 + " str2 = " + str2 + " str3 = " + str3; } }