JAVA基础巩固加强 enhance day1反射 reflect

以前一直只知道有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类就是一个类或者接口对象的一个实例在内存中的字节码,而如何得到一个类的字节码呢?其方法有三:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 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类代表某个类中的一个构造方法。
   得到某个类所有的构造方法: 例子

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> Constructor [] constructors =  Class.forName( " java.lang.String " ).getConstructors();
  
    得到某一个构造方法:
   例子:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> Constructor constructor  =  Class.forName(“java.lang.String”).getConstructor(StringBuffer. class ); // 获得方法时要用到类型
 
    创建实例对象:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> // 通常方式:
String str  =   new  String( new  StringBuffer( " abc " ));
    
// 反射方式: 
String str  =  (String)constructor.newInstance( new  StringBuffer( " abc " )); // 调用获得的方法时要用到上面相同类型的实例对象
   
    Class.newInstance()方法:
   例子:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> String obj  =  (String)Class.forName( " java.lang.String " ).newInstance();
    该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
   该方法内部的具体代码是怎样写的呢?用到了缓存机制来保存默认构造方法的实例对象。
   

下面是一个Field反射的综合实例
将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的"b"改成"a"。 
首先定义一个ReflectPoint的类
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->  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。
齐活儿
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->  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 
结果如下
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--> ** 成员变量的反射 Field **
p1 中  y 
=   - 1
p1 中  x 
=   1
a
= bbll;b = bbsketbbll;c = hello

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值