反射总结

反射机制简介:
      反射基石-->Class类,可以说反射都是基于Class类,掌握反射是必要的,如果你不掌握反射的话,那么你永远只能在低层次打滚,还有就是你想进行高级的框架开发,那是不可能的,但同时Java的面向对象思想在这里也淋漓尽致的体现了,好了,开白就说这么多,下面我们通过一个实例讲解一下,通过反射的方式创建一个新的实例对象。

  (注:以上的异常,本人将其抛出处理,如果你是直接复制代码有错的话,异常跟相关包的导入请自行解决)

  1   一:利用反射创建新实例并调用该类方法:
  2   import java.lang.reflect.Method;
  3 
  4   public class ReflexDemo 
  5   {
  6     public String echo(String name,int age)
  7     {
  8         return name+":"+age;
  9     }
 10     public static void main(String[] args) throws Exception
 11     {
 12         //获取ReflexDemo类所对应的Class对象
 13         Class<?> classType = ReflexDemo.class;
 14         
 15         //利用ReflexDemo类所对应的Class对象,创建一个实例
 16         Object ReflexDemo = classType.newInstance();
 17         
 18         //注意:对于在一个类里面定义的任意一个方法,都会有一个与之相关联的Method对象
 19         //获得echo方法所对应的Method对象
 20         Method method = ReflexDemo.class.getMethod("echo", new Class[]{String.class,int.class});
 21         
 22         
 23         //获得echo方法所对应的Method对象后,通过method(Method)
 24         //所代表echo方法对应的对象调用invoke()方法调用某个对象上它(method==Method)所代表的方法
 25         Object obj = method.invoke(ReflexDemo/*指目标对象*/, new Object[]{"YY",20});
 26         System.out.println(obj);
 27                 
 28     }
 29   }
 30   从上述的实例可以看出,上述所创建的实例方式只能是通过空参数的构造函数(Constructor),而这些并不能满足我们
 31 生活中的开发需要,下面通过实例说明一下,通过多参数的构造函数创建实例。
 32 
 33   二:利用反射获取某类中有多个Constructor参数,来创建实例:
 34 
 35    import java.lang.reflect.Method;
 36 
 37    public class ReflexDemo 
 38    {
 39     public ReflexDemo(String name,int age)
 40     {
 41         System.out.println("姓名: "+name+"年龄: "+age);
 42     }
 43     public static void main(String[] args) throws Exception
 44     {
 45         //得到ReflexDemo类所对应的Class对象
 46         Class<?> classType = ReflexDemo.class;
 47         
 48        //返回构造函数对象
 49        Constructor Constructor = classType.getConstructor( new Class[] {String.class,int.class});
 50         
 51        //通过Constructor创建一个实例
 52        Object obj = Constructor.newInstance("YY",20);            
 53     }
 54    }
 55    三:通过反射获取类中的成员字段(包括公开跟私有):
 56    
 57    1,首先,创建一个类,该类有私有跟公有的成员字段
 58 
 59 
 60    public class ReflexPoint
 61    {
 62     public int x;
 63     private int y;
 64 
 65     public ReflexPoint(int x, int y) 
 66     {
 67         this.x = x;
 68         this.y = y;
 69     }    
 70    }
 71 
 72    2,其次,创建该类实例并获取字段:
 73 
 74 
 75    import java.lang.reflect.Constructor;
 76    import java.lang.reflect.Field;
 77 
 78    public class Demo
 79    {
 80 
 81     public static void main(String[] args)throws Exception 
 82     {
 83         //获取ReflexPoint类所对应的Class对象
 84         Class<?> classType = ReflexPoint.class;
 85         
 86         //获取构造函数对象
 87         Constructor<?> constructor = classType.getConstructor(new Class[]{int.class,int.class});
 88         
 89         //创建实例
 90         Object rp = constructor.newInstance(1,2);
 91         
 92         // 返回一个 Field 对象,注意是所有的公有字段
 93         Field feildX = rp.getClass().getField("x");
 94         
 95         System.out.println(feildX.get(rp));
 96     
 97     }
 98 
 99   }
100 
101   3,对私有字段的获取:
102 
103 
104    import java.lang.reflect.Constructor;
105    import java.lang.reflect.Field;
106 
107    public class Demo
108    {
109 
110     public static void main(String[] args)throws Exception 
111     {
112         //获取ReflexPoint类所对应的Class对象
113         Class<?> classType = ReflexPoint.class;
114         
115         //获取构造函数对象
116         Constructor<?> constructor = classType.getConstructor(new Class[]{int.class,int.class});
117         
118         //创建实例
119         Object rp = constructor.newInstance(1,2);
120         
121         // 返回一个 Field 对象,注意是所有的公有字段
122         Field feildX = rp.getClass().getField("x");
123 
124         //获取类中的所有的字段,包括公有跟私有字段
125         Field feildY = rp.getClass().getDeclaredField("y");
126         
127         //上面一行代码,就算获取到了所有的字段,但还是不能够得到被private修饰的字段,所以我们对私
128         //有字段访问时,取消其权限检查
129         feildY.setAccessible(true);
130                 
131         System.out.println(feildX.get(rp));
132     }
133 
134   }
135 
136   四:通过反射对数组进行操作:
137 
138 
139   1,利用反射动态创建一维数组并对其进行操作:
140 
141 
142    import java.lang.reflect.Constructor;
143    import java.lang.reflect.Field;
144 
145    public class Demo
146    {
147 
148     public static void main(String[] args)throws Exception 
149     {
150         //获取String类所对应的Class对象
151         Class<?> classType = Class.forName("java.lang.String");
152 
153         //动态创建一个类型为ClassType(String)数组,维度(长度)为10
154         Object array = Array.newInstance(classType, 10);
155 
156         //指要对array这个数组的第3个元素设值,设置为“abcdefg”,其余的值为空
157         Array.set(array, 3, "Hello World");
158         
159         //获取array数组中索引值为3的字符
160         String str = (String)Array.get(array, 3);
161        
162         System.out.println(str);
163     }
164 
165   }
166 
167 
168   2,利用反射动态创建多维数组并对其进行操作:
169 
170 
171    import java.lang.reflect.Constructor;
172    import java.lang.reflect.Field;
173 
174    public class Demo
175    {
176 
177     public static void main(String[] args)throws Exception 
178     {
179         int[] dims = new int[]{5,10,15}; 
180         
181         //创建好了一个5 x 10 x 15的三维数组
182          Object arrays = Array.newInstance(Integer.TYPE, dims);
183         //这里取出的是一个二位数组
184         Object arraysObj = Array.get(arrays, 3);//此时是一个一维数组
185         
186         
187         //获得Cass类型 调用getComponentType这个方法返回的是一个二维数组所对应的Class类型
188         Class<?> cls = arraysObj.getClass().getComponentType();
189         
190         
191         //从二维数组中取出一个一维数组
192         arraysObj = Array.get(arraysObj, 5);//此时是一个一维数组
193         
194         
195         //设定这个一维数组中的值为37
196         Array.set(arraysObj, 10, 37);
197         
198         //最后,我们是要取出这个数组,通过普通的方式来获取元素
199         //因为这里是一个三维数组,所以呢,要进行转换
200         int[][][] arrayCast = (int[][][])arrays;
201         
202         System.out.println(arrayCast[3][5][10]);
203     }
204 
205   }

 


  

posted @ 2013-02-23 19:56  全海波  阅读(188)  评论(0编辑  收藏  举报