黑马程序员_java高级篇反射Day10

                       

   ----------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流! --------

                 

                                  黑马程序员_java高级篇反射Day10

 

#java中的Class类#(String.class)


在了解反射之前,先来了解一下Class类,这个并不是新建一个类,我们常常定义类,如许多人,我们可以定义一个Person类,许多类也可以定义一个Class类,Class获得的对象可以包含此类的基本信息,如某个类的类名。

Class cls1=str.getClass();
System.out.println(cls1.isPrimitive());

 

如果我们在程序中定义了三个类,生成了三份字节码,那么我们用Class得到三个类的对象

有三种方法去获得字节码,以下所有的解释都是基于这三种:

 


1,Class c=String.class
2,String str=”abc”; str.getClass()
3,Class.forname(“java.lang.String”);

@对于3,我们要注意一下,一种是内存中已经存在了此字节码,可以直接得到,另一种是还未加载的,那我们会先加载字节码到内存,再得到字节码。@

 


#java中的反射#(依靠对象得到字节码)

 

@反射的定义

定义:反射就是把java类的各种成分,映射成相应的java类

一个java类用一个Class的对象来表示,一个类的组成部分,成员变量,方法,构造方法,包等信息也是一个个java类,就像飞机是一个类,其中的发动机,变速器,黑盒子都是一个个类,表示java类显然要提供一系列的方法没来获得其中的变量方法,构造方法,修饰符,包等信息。

 

@基于String简单的反射机制

步骤:

1 ,首先得到他的构造方法

 

2,用这个构造方法时,还的传一个StringBuffer的对象

 

3,输出


使用反射的机制实现新建字符串,效果如new String( new StringBuffer("abc"));

对于为什么建立反射机制?首先得到他的构造方法,StringBuffer.class这是StringBuffer的字节码

注意getConstructor中可以传入可变参数,可变参数请参考文章《黑马程序员_java高级篇JDK1.5的新特性系列Day9》

 

      

 Constructor cons1=String.class.getConstructor(StringBuffer.class);
      
       //用这个构造方法时,还的传一个StringBuffer的对象
       String strs=(String)cons1.newInstance(new StringBuffer("abc"));
       System.out.println(strs);
 

 

@ Class.forName用于反射

这里怎样得到Filed,Method,怎样去修改配置文件中的属性值,这里的代码都涉及到了。

这里就不一一累赘的解释了,看源代码中的注释

 

 

 

//第三个
       String str2=(String)Class.forName("java.lang.String").newInstance();
      
      
      
       //反射filed,ReflectFiled这是我建的一个类,包含数字与最
       ReflectFiled rf=new ReflectFiled(3,5,"a","b");
      
       //f有好多对象,当我们在这新建rf时,我们可以到的rf的field
       //当我们再一次建立field时,我们同样可以找到,注意如果取x有错,因为它是私有的   
       Field f=rf.getClass().getField("y");
             
       //从某个对应的变量身上取值
       int a=f.getInt(rf);
       System.out.println(a);
 
       Field f1=rf.getClass().getDeclaredField("x");
       //这样设置可以使私有变量可以访问。
       f1.setAccessible(true);
      
       //从某个对应的变量身上取值
       int b=f1.getInt(rf);
       System.out.println(b);
      
       Field[] f2=rf.getClass().getFields();
       //这样设置可以使私有变量可以访问。
       //暂时先将x改为public
       //f2.setAccessible(true);
       for(Field fie:f2)
       {
           if(fie.getGenericType().equals("String"))
           {
              fie.set("name", "2");
           }
       }
       //从某个对应的变量身上取值
      
      
       for(Field fie:f2)
       {
           //因为这里是同一份字节码,所以用==比“equals”更加简明
           if(fie.getType()==(String.class))
           {
              String str3=(String)fie.get(rf);
              fie.set(rf, "ouyang");
              String str4=(String)fie.get(rf);
              System.out.println(str3+":"+str4);
           }
       }
       //反射有什么用呢?
       //当我们用反射时,我们可以修改一些配置文件中的参数,这也是反射的机制之一。
   
       //第四  method
   //  用反射的方法怎么做如str.charAt()
      
       //arg0对应方法名,arg1对应的表示我们到底想从重载的方法中选择哪一个呢
       //我们平时写程序是靠参数实现的,每一个参数都用arg1来表示,arg1是一个class
       //arg1就是我们所说的class可变参数
       String str5="aa";
       //得到方法
    java.lang.reflect.Methodm=String.class.getMethod("charAt",int.class);
   
       //作用于某个对象,当我们把str5改为null表示调用静态方法
        System.out.println(m.invoke(str5,1));
       
       
        //面向对象中面试常考的,就是我们所说的人关门的问题,
        //如果你推了一下门,门关了,那门是呢关的吗?不是的你只是个门一个信号,
        //关门动作实在门身上的,这就是所谓道德专家模式,谁有数据谁就是专家
       
      
       // JDK1.4与JDK1.5的小差别
        /*
         * 由于jdk1.4是没有可变参数的,但我们传入的参数不知道是多少时,我们
         * 要传入一个数组
         */
       


@反射与内存

反射需要缓存,会使程序的性能下降。

就是对于我们上面解释的三种反射方法

1,Class c=String.class
2,String str=”abc”; str.getClass()
3,Class.forname(“java.lang.String”);


 

2与3其实想比较,3比二省了一个步骤,其实3还是用的2,只是有封装了一层,里面用到了cache,对比一下:

(2)

Constructor cons1=String.class.getConstructor(StringBuffer.class);
      
       //用这个构造方法时,还的传一个StringBuffer的对象
       String strs=(String)cons1.newInstance(new StringBuffer("abc"));
       System.out.println(strs);


 

(3)

 

String str2=(String)Class.forName("java.lang.String").newInstance();

当我们查看newInstance()源代码时,我们会发现里面有cache,它是将得到的字节码先存在内存中,在来获取。

 


   ----------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流! --------

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值