分享

Java开发笔记 — 反射

 openwudi 2010-10-08

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 <len ; 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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多