andy-j2ee  
JAVA
公告
  • 在夜深人静的时候,偶弹起心爱的土琵琶,唱起那动人的歌谣(柯受良-《大哥》):偶写了代码好多年,偶不爱冰冷的床沿,不要逼偶想念,不要逼偶流泪,偶会翻。
日历
<2011年11月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910
统计
  • 随笔 - 19
  • 文章 - 1
  • 评论 - 1
  • 引用 - 0

导航

常用链接

留言簿

随笔分类(5)

随笔档案(19)

文章分类(1)

文章档案(1)

搜索

  •  

最新评论

阅读排行榜

评论排行榜

 
    以前一直只知道有reflect这么一个类是用来反射的,听人家说java中的反射很难,晚上听罢张老师讲的反射这一节的内容,惶然大悟,原来反射就是把Java类中的各种成分映射成相应的java类。    
    反射的基础是要掌握Class这个类的,具体Class的类是干什么的,下面是api文档中的解释
   
api中关于Class类的一段描述
Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind of class and an annotation is a kind of interface. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions. The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects.
翻译成中文
Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(booleanbytecharshortintlongfloatdouble)和关键字 void 也表示为 Class 对象。
    可以看出Class类就是一个类或者接口对象的一个实例在内存中的字节码,而如何得到一个类的字节码呢?其方法有三:
1         Class<? extends String> cls1 = str1.getClass();
2         Class<String> cls2 = String.class;
3         Class<?> cls3 = Class.forName("java.lang.String");
    而Class的isPrimitive()方法就是用来判断一个类的字节码是不是9个预定义的class
    
    接下来是Constructor类,Constructor类代表某个类中的一个构造方法。
   得到某个类所有的构造方法: 例子
Constructor [] constructors= Class.forName("java.lang.String").getConstructors();
  
    得到某一个构造方法:
   例子:
Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);//获得方法时要用到类型
 
    创建实例对象:
//通常方式:
String str = new String(new StringBuffer("abc"));
    
//反射方式: 
String str = (String)constructor.newInstance(new StringBuffer("abc"));//调用获得的方法时要用到上面相同类型的实例对象
   
    Class.newInstance()方法:
   例子:
String obj = (String)Class.forName("java.lang.String").newInstance();
    该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
   该方法内部的具体代码是怎样写的呢?用到了缓存机制来保存默认构造方法的实例对象。
   

下面是一个Field反射的综合实例
将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的"b"改成"a"。 
首先定义一个ReflectPoint的类
 1 package com.anduo.day1;
 2 
 3 public class ReflectPoint {
 4     private int x;
 5     public int y;
 6     public String a = "ball";
 7     public String b = "basketball";
 8     public String c = "hello";
 9 
10     public ReflectPoint(int x, int y) {
11         super();
12         this.x = x;
13         this.y = y;
14     }
15 
16     @Override
17     public String toString() {
18         return "a=" + a + ";b=" + b + ";c=" + c;
19     }
20 }
21 

下面的步骤是:先从对象中得到所有为String类型的字段,2:得到Sting字段的值;3:用String类的replace方法代换a字符为b字符;4:把对象的String字段设置为修改完的新String。
齐活儿
 1 package com.anduo.day1;
 2 
 3 import java.lang.reflect.Constructor;
 4 import java.lang.reflect.Field;
 5 
 6 public class ReflectTest {
 7 
 8     
 9     public static void main(String[] args) throws Exception {
10 
11         
12         /**
13          * 成员变量的反射 Field
14          */
15         System.out.println("**成员变量的反射 Field**");
16         ReflectPoint pt1 = new ReflectPoint(1-1);
17         Field fieldY = pt1.getClass().getField("y");
18         // fieldY 不是对象身上的变量,而是类上,要用它来去对象上字段的值
19         System.out.println("p1 中  y = " + fieldY.get(pt1));
20         Field fieldX = pt1.getClass().getDeclaredField("x");// 获取私有属性字段
21         fieldX.setAccessible(true);// 暴力反射
22         System.out.println("p1 中  x = " + fieldX.get(pt1));
23 
24         /**
25          * 将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的"b"改成"a"
26          */
27         changeStringValue(pt1);
28         System.out.println(pt1);
29     }
30 
31     /**
32      * 将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的"b"改成"a"
33      * @param obj
34      * @throws IllegalArgumentException
35      * @throws IllegalAccessException
36      */
37     private static void changeStringValue(Object obj) throws IllegalArgumentException, IllegalAccessException {
38         Field[] fields = obj.getClass().getFields();
39         for (Field field : fields) {
40             // if(field.getType().equals(String.class))
41             if (field.getType() == String.class) {
42                 String oldValue = (String) field.get(obj);
43                 String newValue = oldValue.replace('a''b');
44                 field.set(obj, newValue);
45             }
46         }
47     }
48 
49 }
50 
结果如下
**成员变量的反射 Field**
p1 中  y 
= -1
p1 中  x 
= 1
a
=bbll;b=bbsketbbll;c=hello

综上可以看出,其实反射也没多难,人家那些写框架的也不就是用了些反射吗?把配置文件中的东西读出来,然后再调用下面的类去做应该做的事情,当然这个过程就用到了反射了。

posted on 2011-11-07 20:58 安多 阅读(308) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航:
 
 
Copyright © 安多 Powered by: 博客园 模板提供:沪江博客