Java中的反射,我们常见是取得构造方法,成员变量,普通方法,还有对数组反射的操作。
1、反射的精辟定义:反射就是把Java类中的各种成分映射成相应的Java类。
2、Class实例表示正在运行的Java应用程序中的类和接口。所有的
3、反射除了方法体得不到,别的都可以得到。包括可以得到类里私有的成员变量。本人觉得这破坏了Java的封装性,不知道为什么要这么设计。
一、构造方法的反射
(1)得到需要反射的类Class。知道类名可以使用forName(String className) 方法。也可以通过对象的.getClass方法获得。或者明确去获得哪个类型。比如我们有一个Person类,我们想得到这个类的实例可以写成 Person.class。
(2)构造方法用Constructor类表示。可以通过刚才得到的Class,使用getConstructor方法获得,想获得什么形参的构造方法,就传入什么形参类型的Class,比如想取得String的String(StringBuffer buffer) 构造方法可以这样:String.class.getConstructor(StringBuffer.class)。
(3)使用取得的构造方法创建对象,我们需要使用newInstance方法,形参为可变参数,按上面取得的String的构造方法,我们就可以这样创建对象,String.class.getConstructor(StringBuffer.class).newInstance(new StringBuffer())
二、成员变量的反射
(1)我们同样需要取得反射的类Class。
(2)Java中使用Field类表示字段,我们想获得成员变量可以使用Class的getField(String name)方法,参数为成员变量的名字。也有getFields()方法取得该类的所有成员变量,返回值为Field的数组。取得Field的值,使用 get方法,设置值使用set方法。
(3)暴力访问私有成员使用setAccessible方法,getType() 取得Field类型,getName()取得Field的字段名称。
三、普通方法的反射
(1)取得反射类Class。
(2)方法使用Method类定义,获得方法使用getMethod(String name, Class… parameterTypes) ,用法很像获得构造方法,只是多出一个方法名的参数。
(3)getReturnType()获得方法的返回值类型,getParameterTypes()获得所有形参类型。
(4)用invoke调用方法第一个参数为需要调用的对象,第二个参数为用于调用的参数。
综合范例如下:
Java语言: ReflectCase.java
001 package com.openwudi.reflect;
002
003 import java.lang.reflect.Array;
004 import java.lang.reflect.Constructor;
005 import java.lang.reflect.Field;
006 import java.lang.reflect.Method;
007 import java.util.Arrays;
008
009 public class ReflectCase {
010
011 /**
012 * @author WuDi
013 */
014 public static void main(String[] args) throws Exception {
015 // TODO Auto-generated method stub
016 ReflectPoint p1 = new ReflectPoint(3, 5);
017 //获得构造方法
018 ReflectPoint p2 = (ReflectPoint) getConstructor();
019 System.out.println(p2);
020 //改变成员变量
021 changeStringField(p1);
022 System.out.println(p1);
023 //方法反射
024 methodReflect("a");
025 //数组的反射
026 arrayReflect();
027 }
028
029 private static void arrayReflect() {
030 int[] aOne = new int[3];
031 int[] aTwo = new int[4];
032 int[][] aThree = new int[2][5];
033 String[] aFour = new String[3];
034 //维度和类型相同的数组的Class是相同的
035 System.out.println(aOne.getClass() == aTwo.getClass());
036 //System.out.println(aOne.getClass() == aThree.getClass());
037 //System.out.println(aOne.getClass() == aFour.getClass());
038
039 //数组可以转换成Object类型
040 Object o1 = aOne;
041 Object o2 = aTwo;
042 Object o3 = aThree;
043 Object o4 = aFour;
044 //基本数据类型数组,不能转换成Object数组
045 Object[] oa1 = aThree;//oa1等价与{new int[5],new int[5]}
046 Object[] oa2 = aFour;
047 // Arrays工具类
048 aOne = new int[] { 1, 2, 3 };
049 aFour = new String[] { "a", "b", "c" };
050 System.out.println(Arrays.asList(aOne));// 显示:[[I@9cab16]
051 System.out.println(Arrays.asList(aFour));// 显示:[a, b, c]
052 //数组反射
053 printObject(aFour);
054 printObject("abc");
055 }
056
057 private static void printObject(Object obj) {
058 Class clazzStr = obj.getClass();
059 if (clazzStr.isArray()) {
060 int len = Array.getLength(obj);
061 for(int i = 0 ; i
062 System.out.println(Array.get(obj, i));
063 }
064 }
065 }
066
067 private static void methodReflect(String string) throws Exception {
068 Class clazzStr = String.class;
069 Method[] strMethods = clazzStr.getDeclaredMethods();
070 for (Method method : strMethods) {
071 System.out.print(method.getName()+"(");
072 for(Class para : method.getParameterTypes()){
073 System.out.print(para.getName()+" ");
074 }
075 System.out.println(")");
076 }
077 String s1 = "aaa";
078 System.out.println(clazzStr.getMethod("length", null).invoke(s1, null));
079 }
080
081 private static Object getConstructor() throws Exception {
082 Class clazzP2 = Class.forName("com.openwudi.reflect.ReflectPoint");
083 Constructor constructor = clazzP2.getConstructor(int.class);
084 ReflectPoint p2 = (ReflectPoint) constructor.newInstance(15);
085 return p2;
086 }
087
088 private static void changeStringField(Object p1)
089 throws IllegalAccessException {
090 Class clazzP1 = p1.getClass();
091 Field[] fields = clazzP1.getDeclaredFields();
092 for (Field f : fields) {
093 if (f.getType() == String.class) {
094 String oldStr = (String) f.get(p1);
095 f.set(p1, oldStr.replace('b', 'a'));
096 }
097 }
098 }
099
100 }
附加被调用类源码:
Java语言: ReflectPoint.java
01 package com.openwudi.reflect;
02
03 public class ReflectPoint {
04 private int x = 1;
05 public int y = 2;
06 public String str1 = "ball";
07 public String str2 = "basketball";
08 public String str3 = "wudi";
09
10 public ReflectPoint(int x) {
11 this.x = x;
12 }
13
14 public ReflectPoint(int x, int y) {
15 super();
16 this.x = x;
17 this.y = y;
18 }
19
20 @Override
21 public String toString() {
22 return x + ":" + y + ":" + str1 + ":" + str2 + ":" + str3;
23 }
24 }
运行结果:
控制台运行效果:
15:2:ball:basketball:wudi
3:5:aall:aasketaall:wudi
hashCode()
compareTo(java.lang.Object )
compareTo(java.lang.String )
indexOf(java.lang.String int )
indexOf([C int int [C int int int )
indexOf(java.lang.String )
indexOf(int )
indexOf(int int )
equals(java.lang.Object )
toString()
charAt(int )
checkBounds([B int int )
codePointAt(int )
codePointBefore(int )
codePointCount(int int )
compareToIgnoreCase(java.lang.String )
concat(java.lang.String )
contains(java.lang.CharSequence )
contentEquals(java.lang.StringBuffer )
contentEquals(java.lang.CharSequence )
copyValueOf([C int int )
copyValueOf([C )
endsWith(java.lang.String )
equalsIgnoreCase(java.lang.String )
format(java.lang.String [Ljava.lang.Object; )
format(java.util.Locale java.lang.String [Ljava.lang.Object; )
getBytes(java.nio.charset.Charset )
getBytes()
getBytes(java.lang.String )
getBytes(int int [B int )
getChars(int int [C int )
getChars([C int )
intern()
isEmpty()
lastIndexOf(java.lang.String )
lastIndexOf(int )
lastIndexOf(int int )
lastIndexOf([C int int [C int int int )
lastIndexOf(java.lang.String int )
length()
matches(java.lang.String )
offsetByCodePoints(int int )
regionMatches(int java.lang.String int int )
regionMatches(boolean int java.lang.String int int )
replace(char char )
replace(java.lang.CharSequence java.lang.CharSequence )
replaceAll(java.lang.String java.lang.String )
replaceFirst(java.lang.String java.lang.String )
split(java.lang.String int )
split(java.lang.String )
startsWith(java.lang.String int )
startsWith(java.lang.String )
subSequence(int int )
substring(int )
substring(int int )
toCharArray()
toLowerCase()
toLowerCase(java.util.Locale )
toUpperCase()
toUpperCase(java.util.Locale )
trim()
valueOf([C )
valueOf(int )
valueOf(long )
valueOf(float )
valueOf(double )
valueOf(java.lang.Object )
valueOf(char )
valueOf([C int int )
valueOf(boolean )
3
true
[[I@1f1fba0]
[a, b, c]
a
b
c