您的位置:首页 > 编程语言 > Java开发

Java反射

2014-03-14 23:19 323 查看
反射的概念:
         反射就是把java类中的各种成份映射成相应的java类。例如,一个java类中的用一个Class类的对象来表示,一个类中的组成部分,成员变量、方法、构造函数、包等等信息也用一个个java类来表示。表示java类的Class类显然要提供一系列的方法,来获得其中的变量、方法、构造函数、修饰 符、包等信息,这些类就是用相应的类的实例对象来表示,他们是Filed、Method、Constructor、Package等。
         一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示,通过调用Class类的方法可以得到这些实例对象
 
 
反射的用途:
         反射的主要作用是:用来扩展系统和动态调用程序集。

         扩展系统
:就是先把系统写好,系统里面定义接口,后面开发的人去写接口的代码。

此时该系统就要用反射了,系统用反射调用接口,当接口没写,系统利用反射就不会不会出错,此时就等于没实现此功能而已,当接口被人写好了,系统就会自动调用接口的功能展现在系统上。即反射实现即插即用功能。
        动态调用程序集就是利用反射去调用编译好的程序,反射具有一定灵活性,不需改变你所建的工程。
 
反射最主要的用户适用于做框架的
 
反射的基石-Class类:
如何得到各个字节码对应的实例对象
类名:class,例如System.class
对象.getClass(),例如,new Date().getClass();
Class.forName(“类名”),例如Class.forName(“java.util.Date”);
 
publicclassReflectDemo1 {
 
    publicstaticvoid main(String[] args)
throwsException {
        Stringstr1 =
"abc";
        //得到字节码的三种方式
        Classcls1 =str1.getClass();
        Classcls2 = String.class;
        Classcls3 = Class.forName("java.lang.String");
        System.out.println(cls1 == cls2);//true
        System.out.println(cls1 == cls3);//true
       
        //打印出是否是基本類型
        System.out.println(cls1.isPrimitive());//false
        System.out.println(int.class.isPrimitive());//true
        System.out.println(int.class
== Integer.class);//false
        System.out.println(int.class
== Integer.TYPE);//true
        System.out.println(int[].class.isPrimitive());//false
        System.out.println(int[].class.isArray());//true
    }
 
}
 
总之,只要在源程序中出现的类型,都有各自的Class实例对象,例如int[],void
 
得到字节码的三种方式:
publicclassReflectDemo1 {
 
   publicstaticvoidmain(String[] args)
throws Exception {
      Stringstr1 =
"abc";
      //得到字节码的三种方式
      Classcls1 =str1.getClass();
      Classcls2 = String.class;
      Classcls3 = Class.forName("java.lang.String");
      System.out.println(cls1 == cls2);//true
      System.out.println(cls1 == cls3);//true
     
      //打印出是否是基本類型
      System.out.println(cls1.isPrimitive());//false
      System.out.println(int.class.isPrimitive());//true
      System.out.println(int.class
== Integer.class);//false
      System.out.println(int.class
== Integer.TYPE);//true
      System.out.println(int[].class.isPrimitive());//false
      System.out.println(int[].class.isArray());//true
}
 
成员构造函数的反射:
使用到的ReflectPoint类
publicclassReflectPoint {
   privateintx;
   publicinty;
   public ReflectPoint(int x,
int y) {
      super();
      this.x = x;
      this.y = y;
   } 
}
 
publicclassReflectDemo2 {
 
   publicstaticvoidmain(String[] args)
throws Exception {
//new String(new StringBuilder("abc"));
      //得到类型
      Constructorconstructor1= String.class.getConstructor(StringBuilder.class);
      //得到方法的对象
      Stringstr2 = (String) constructor1.newInstance(new StringBuilder("c"));
      System.out.println(str2);
}
}
字段的反射:
使用到的ReflectPoint类
publicclassReflectPoint {
   privateintx;
   publicinty;
   public ReflectPoint(int x,
int y) {
      super();
      this.x = x;
      this.y = y;
   } 
}
publicclassReflectDemo2 {
 
   publicstaticvoidmain(String[] args)
throws Exception {
ReflectPoint rp = newReflectPoint(3,5);
      FieldfieldY = rp.getClass().getField("y");
      System.out.println(fieldY.get(rp));
     
      Fieldfieldx = rp.getClass().getDeclaredField("x");
      fieldx.setAccessible(true);
      System.out.println(fieldx.get(rp));
}
}
 
反射成员变量的综合案例:
publicclassReflectPoint {
   privateintx;
   publicinty;
   public String
str1 =
"ball";
   public String
str2 =
"basketball";
   public String
str3 =
"itcast";
 
   public ReflectPoint(int x,
int y) {
      super();
      this.x = x;
      this.y = y;
   }
 
   //@Override可以判断重载的方法是否写正确
   @Override
   public String toString(){
      return"ReflectPoint [x="+
x + ", y=" +
y + ", str1="+
str1
           +", str2="+
str2+
", str3="+ str3+
"]";
   }
  
}
 
 
publicclassReflectDemo2 {
 
   publicstaticvoidmain(String[] args)
throws Exception {
      //操作field字段
      changeStringValue(rp);
      System.out.println(rp);
}
 
privatestaticvoidchangeStringValue(Object obj)
throwsException {
      Field[]fields = obj.getClass().getFields();
      for(Field field : fields) {
         //比较同一份字节码使用==而不是使用equals
         if(field.getType() ==String.class){
           Stringvalue = (String) field.get(obj);
           StringnewValue = value.replace('b',
'a');
           field.set(obj,newValue);
         }
      }
   }
}
 
反射得到类的方法:
methodCharAt.invoke(null, 1)当第一个参数为null时,意味着调用的是静态的方法
//jdk1.4的语法来调用
System.out.println(methodCharAt.invoke(str1,newObject[] {2}));
//jdk1.5的语法来调用
System.out.println(methodCharAt.invoke(str1, 1));
publicclassReflectDemo1 {
   publicstaticvoidmain(String[] args)
throws Exception {
      Stringstr1 =
"abc";
      //得到类的方法,String.charAt方法
      MethodmethodCharAt = String.class.getMethod("charAt",
int.class);
   //methodCharAt.invoke(null,1)当第一个参数为null时,意味着调用的是静态的方法
      System.out.println(methodCharAt.invoke(str1,1));//jdk1.5的语法来调用
System.out.println(methodCharAt.invoke(str1,newObject[] {2}));//jdk1.4的语法来调用
 
}
}
 
 
反射执行某个类中的main方法:
对接收数组参数的成员方法进行反射
 
方法一:     mainMethod.invoke(null,
new Object[]{new
String[] {"111","222","333"}});
方法二:     mainMethod.invoke(null, (Object)newString[]{"111","222","333"});
 
 
publicclassReflectDemo1 {
 
   publicstaticvoidmain(String[] args)
throws Exception {
//反射执行某个类中的main方法
      StringstartingClassName = args[0];
      MethodmainMethod =Class.forName(startingClassName).getMethod("main", String[].class);
      mainMethod.invoke(null,
new Object[]{new String[] {"111","222","333"}});
      mainMethod.invoke(null, (Object)new String[]
{"111","222","333"});
         }
}
 
classTestArguments {
   publicstaticvoidmain(String[] args) {
      for(String s : args) {
         System.out.println(s);
      }
   }
}
 
注意在运行的时候要传递TestArguments类的包给ReflectDemo1
 
数组的反射:
publicclassReflectDemo1 {
 
   publicstaticvoidmain(String[] args)
throws Exception {
int[]a1 =newint[3];
      int[] a2 =
newint[4];
      int[][] a3 =
newint[2][3];
      String[] a4 = new String[] {"abc","bcd","cde"};
      System.out.println(a1.getClass()== a2.getClass());
//    System.out.println(a1.getClass()== a4.getClass());
//    System.out.println(a1.getClass()== a3.getClass());
      System.out.println(a1.getClass().getName());
      System.out.println(a1.getClass().getSuperclass().getName());
      System.out.println(a4.getClass().getSuperclass().getName());
     
      Object aObj1 = a1;
      Object aObj2 = a4;
//    Object[] aObj3= a1;
      Object[] aObj4 = a3;
      Object[] aObj5 = a4;
     
      System.out.println(a1);
      System.out.println(a4);
      System.out.println(Arrays.asList(a1));
      System.out.println(Arrays.asList(a4));
 
}
}
 
数组的反射应用:
publicclassReflectDemo1 {
 
   publicstaticvoidmain(String[] args)
throws Exception {
String[] a4 = newString[]{"abc","bcd","cde"};
      printObject(a4);
      printObject("xyz");
   }
 
     privatestaticvoidprintObject(Object obj) {
      Classclazz = obj.getClass();
      if(clazz.isArray()) {
         int len = Array.getLength(obj);
         for(int i = 0; i < len; i++){
           System.out.println(Array.get(obj,i));
         }
      }else{
         System.out.println(obj);
      }
   }
}
 
 
 
反射的综合案例:
ArrayList_HashSet的比较以及HashCode的分析
 
ArrayList是线性的存放,有多少放多少,按照先后的顺序
HashSet是存放不重复的,存放之前先判断集合中是否存在,不存在才放入
HashCode是一种编码方式,在Java中,每个对象都会有一个hashcode,Java可以通过这个hashcode来识别一个对象
publicclassReflectDemo2 {
 
   publicstaticvoidmain(String[] args) {
      Collectioncollection=
newHashSet();
      ReflectPointpt1 =
new
ReflectPoint(3, 3);
      ReflectPointpt2 =
new
ReflectPoint(5, 5);
      ReflectPointpt3 =
new
ReflectPoint(3, 3);
     
      collection.add(pt1);
      collection.add(pt2);
      collection.add(pt3);
      collection.add(pt1);
     
/*
*此处并不能移走pt1,因为将数据加入hashset中以后不能再去更改他,
这样会导致内存泄露
 
内存泄露的作用,此处是一个例子,java中有内存泄露吗?为什么?
      pt1.y= 7;
      collection.remove(pt1);
      */
      System.out.println(collection.size());
     
   }
 
}
 
packagecom.wj.reflect;
 
publicclassReflectPoint {
   privateintx;
   publicinty;
   public ReflectPoint(int x,
int y) {
      super();
      this.x = x;
      this.y = y;
   }
 
   @Override
   publicint hashCode() {
      finalint prime = 31;
      int result = 1;
      result= prime * result +
x;
      result= prime * result +
y;
      return result;
   }
 
   @Override
   publicbooleanequals(Object obj) {
      if (this == obj)
         returntrue;
      if (obj ==
null)
         returnfalse;
      if (getClass() !=obj.getClass())
         returnfalse;
      ReflectPointother = (ReflectPoint) obj;
      if (x != other.x)
         returnfalse;
      if (y != other.y)
         returnfalse;
      returntrue;
   }
 
   @Override
   public String toString(){
      return"ReflectPoint [x="+
x + ", y=" +
y + ", str1="+
str1
           +", str2="+
str2+
", str3="+ str3+
"]";
   }
  
}
用类加载器管理资源和配置文件,也会使用到反射。详见另一篇博客
 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  反射 reflect