杰点

hello java

反射

反射的基础是Class类
Class:

 JAVA类用于描述一类事物的共性。而是什么属性则是由类的实例对象来确定的,不同的实例对象有不同的属性值。

 Class则是用于描述JAVA类的共性的类,描述了类的名字,访问属性,包名,字段名称列表,方法名称列表等。

 Class的实例对象为某个类的字节码。
  获取字节码的实例对象方法有三种
  1. 类名.class  System.class
  2. 对象.getClass  new Date().getClass()
  3. Class.forName("类名") Class.forName("java.util.Date")
 

 Class cls1=Date.class //Date类的字节码 ,已经加载到内存
 Class cls2=p1.getClass();//调用对象的getClass()得到类的字节码
 Class.forName("java.lang.String") //返回该类字节码

反射就是把Java类中的各种成分映射成相应的Java类,如:一个Java类中用Class类的对象来表示,一个类中组成的部分:
成员变量,方法,构造方法,包等信息,也是用一个个Java类来表示的

 Class代表一份类字节码

 Method 类的实例对象代表 类的方法

Constructor类
 Constructor类代表类中的一个构造方法

 //获取某个类的所有构造方法
 Constructor[] constructors=Class.forName("java.lang.String").getConstructors();

 //获取某个构造方法,要用的参数类型 如:String(StringBuffer buffer)
 Constructor constructor=Class.forName("java.lang.String").getConstructor(StringBuffer.class);

创建实例对象
 通常方法:String str=new String(new StringBuffer("abcd"));
   //Constructor类的 newInstance() 方法
 反射方法:String str=(String)constructor.newInstance(new StringBuffer("abc"))

Field类,代表某个类的属性
  Field fieldy=pt1.getClass().getField("y");  得出的是类的属性,值是不固定的,根据对象来确定
  fieldy.get(pt1);

  改field需要调用fieldy.set(obj,value);

Method类
 getMethod(name,parameterytpes) //类名,方法参数类型

 //执行方法用invoke(obj,parameters)
 Method methodCharAt=String.class.getMethod("charAt",int.class)
 //静态方法 name=null
 methodCharAt.invoke(str1,1);

 

 1 //创建一个测试反射的类
 2 public class ReflectPoint {
 3     private int x;
 4     public int y;
 5     public String str1="china";
 6     public String str2="basketbool";
 7     public String str3="itcast";
 8     public ReflectPoint(int x, int y) {
 9         super();
10         this.x = x;
11         this.y = y;
12     }
13     
14 }
15 


 

  1 //反射测试
  2 import java.lang.reflect.*;
  3 public class ReflectTest {
  4 
  5     /**反射基本知识
  6      * 
  7      * 反射就是把java类中的各个成分映射为java类
  8      * 反射的基础是Class类,它是java类的描述类,Class类的实例是某个类的字节码
  9      * @param args
 10      */
 11     public static void main(String[] args) throws Exception {
 12         // TODO Auto-generated method stub
 13         //Class测试
 14         //Class的实例是类的字节码
 15         String str1="abcde";
 16         
 17         //获取Class实例的三种方式
 18         Class cls1= str1.getClass(); //获取该对象类的字节码
 19         Class cls2=String.class;  //直接调用类的字节码
 20         Class cls3=Class.forName("java.lang.String");//根据类名获取字节码
 21         
 22         System.out.println(cls1==cls2);                    //true
 23         System.out.println(cls1==cls3);                    //true
 24         
 25         //isPrimitive()是否是基本数据类型的字节码 8种+void
 26         System.out.println(cls1.isPrimitive());         //false
 27         System.out.println(Integer.class.isPrimitive());//false
 28         System.out.println(int.class.isPrimitive());    //true
 29         
 30         //Integer.TYPE常量 代表包装的基本类型 的 字节码
 31         System.out.println(int.class==Integer.TYPE);     //true
 32         
 33         //数组不是基本数据类型,是对象
 34         System.out.println(int[].class.isPrimitive());     //false
 35         System.out.println(int[].class.isArray());       //true
 36         
 37         //得到String类的 String(StringBuffer)构造方法
 38         Constructor constructor=String.class.getConstructor(StringBuffer.class);
 39         //可以构造方法,创建实例 ,并进行类型转换
 40         String str2 = (String)constructor.newInstance(new StringBuffer("abcsd"));
 41         
 42         ReflectPoint pt1=new ReflectPoint(3,5);
 43         
 44         //Field类
 45         Field fieldy=pt1.getClass().getField("y");
 46         //fieldy的值是5吗? 不是,fieldy不代表具体的值,只代表类的y变量
 47         //因为取的是类的字节码,类中变量的值是根据 对象来决定的
 48         //通过.get(object) 来获取某个对象的值
 49         System.out.println(fieldy.get(pt1));
 50         
 51         Field fieldx=pt1.getClass().getDeclaredField("x");//获取声明过的属性
 52         fieldx.setAccessible(true); //访问权限设置为true
 53         System.out.println(fieldx.get(pt1)); 
 54         
 55         changeString(pt1);
 56         System.out.println(pt1.str1);
 57         System.out.println(pt1.str2);
 58         System.out.println(pt1.str3);
 59         
 60         //Method
 61         //取得类字节码 中的charAt方法
 62         Method methodCharAt=String.class.getMethod("charAt"int.class);
 63         //调用invoke(obj,parameter) 执行方法
 64         System.out.println(methodCharAt.invoke(str1,1));
 65         
 66         
 67         //调用main()方法,普通方式
 68         // TestArguments.main(new String[]{"abc","1111"});
 69         //使用反射调用,为了解决,给定类名,而不知道实现代码的情况下用
 70         //从类字节码 得到 main方法
 71         Method methodmain=Class.forName(args[0]).getMethod("main",String[].class);
 72         methodmain.invoke(null,new Object[]{new String[]{"abc","1111"}});
 73         
 74         //数组的反射
 75         int[] a1=new int[3];
 76         int[] a2=new int[4];
 77         int[][] a3=new int[2][3];
 78         String[] a4=new String[2];
 79         //数组的字节码比较,看的是数组类型和数组维度
 80         System.out.println(a1.getClass()==a2.getClass()); //true  
 81         System.out.println(a1.getClass()==a3.getClass()); //false
 82         System.out.println(a1.getClass()==a4.getClass()); //false
 83         System.out.println(a3.getClass()==a4.getClass()); //false
 84         //获取父类
 85         System.out.println(a1.getClass().getName());
 86         System.out.println(a1.getClass().getSuperclass().getName());
 87         System.out.println(a4.getClass().getSuperclass().getName());
 88         //得出父类都是Object类
 89         Object aobj1=a1;
 90         Object aobj2=a2;
 91         Object aobj4=a4;
 92         //Object[] aobj5=a1; //里面装的是基本类型,基本类型不是对象,不能装入
 93         Object[] aobj5=a3;
 94         
 95         int[] t1=new int[]{12,34,2};
 96         printObject(t1); //打印对象,数组是对象,但t1数组元素是基本类型
 97         printObject("xyz"); //打印对象
 98                             
 99     }
100 
101     private static void printObject(Object obj){
102         Class clazz=obj.getClass(); //获取该对象类的字节码
103         if(clazz.isArray()){
104             //Array是数组的反射类
105             for(int i=0;i<Array.getLength(obj);i++){
106                 System.out.println(Array.get(obj, i));
107             }
108         }else{
109             System.out.println(obj);
110         }
111     } 
112     
113     private static void changeString(Object obj){
114         Field[] fields=obj.getClass().getFields();
115         for(Field field:fields){
116             if(field.getType()==String.class){//同一份字节码 用==
117                 try {
118                     String newValue=((String)field.get(obj)).replace('a''b');
119                     field.set(obj, newValue);
120                 } catch (Exception e) {
121                     // TODO: handle exception
122                 }
123             }
124         }
125     }
126 }


 

posted on 2010-12-29 13:21 杰点 阅读(329) 评论(0)  编辑  收藏 所属分类: JAVA


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


网站导航:
 
<2025年7月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

导航

统计

留言簿

文章分类

文章档案

搜索

最新评论