黑马程序员----反射

                                                                           第一部分

基础知识篇:

反射的定义:反射就是把java类中的各种成分映射成相应的java类,获取的变量,方法,构造方法,修饰符等这些信息就用相应的java类表示

                       它们是Filed,Method,Constructor,Package等

 

发射的基石:Class ,java程序中各个java类属于同一事物,描述这一类事物的类名就是Class

                        可以对比前面的学习 众多的人可以用Person类描叙,众多的java类可以用Class描述

                        其实Class类的对象就是一类字节码,我么可以通过Class类的方法获得加载到内存中的字节码的构造方法,

                        类的名称,类的所属包,类的成员变量,父类等

 

获取字节码对象的方法:

(1)  通过点运算符获取:比如我们已经导入一个person()类到内存,现在我们可以通过一个对象p1.getClass()方法获取

(2)  通过指定完整的类名获取:例如class.forName( “java.lang.String”)

(3)  直接在源程序中写出 例如我们需要Data类 可以通过Class cls =Data.class获取 例如System.class,编译器可以自动识别

 

九个预定义class类型:8基础数据类型class数据对象:boolean,byte,char,short,int,,long,float,double和void

 

 

                                    第二部分:反射的应用举例

Constructor可获取全部构造方法或者其中一个构造方法

例如:String str = new String(new stringBuffer("abc"))可以通过反射方法得到相同结果

//得到一个Constructor类的对象cons,cons对象可以得到这个类的一些属性(getDeclearingClass()得到所属的类,getModifier()得到修饰符,)这里举例

//newInstence()方法,下面用此方法建立对象

Constructor cons = ClassforName(“java.lang.String”).getConstructor(StringBffer.class);

//上面一条语句StringBuffer表示选择哪一个构造方法,这一条语句表示用这个构造方法时候还在传StringBuffer的对象进去

//cons前面的强转是因为编译的时候不知道cons是什么类型的构造方法

String str = (String)cons.newInstance(new StringBuffer("abc"));

 

 类的成员变量Filed类,获取类的某一字段,比如成员变量

先建立一个类

class Filed

{

    public int  x=3;

    private int y=5;

    public Filed(int x,int y)

    {

          this.x=x;

          this.y=y;

    }

}

Filed f=new Filed(3,5)

Filed filedx=f.getClass().getFiled("x")

//现在获得的filedx并不是3,因为他是一个类的字段,并不是一个具体的值

//可以通过get方法获取某一个对象上的值

System.out.println(filedx.get(f));

注意:

当变量为私有的时候 有两步不一样

//gerDeclearFiled()设置可见

Filed filedy=f.getClass().getDeclearedFiled("y")

//setAccessable(ture)设置可见

filedx.setAccessable(ture);

System.out.println(filedy.get(f));

 

Method类:获取某个类的成员方法

在String的各个对象中 任意一个字符串对象都可以调用CharAt方法,现在可以通过反射的方式由任意一个对象得到此方法

例如:String str = “abc”  str.charAt(1)

//指定方法名称和方法参数类型

Method methodcharat = String.class.getMethod("charAt",int.class)

//返回的方法methodcharat,再用方法作用于对象,invoke表示函数的调用动作

System.out.println(methodcharat.invoke(str,1))

 

 

用反射方式调用某个类的main方法

例如:

class demo

{

       public static void main(String [ ] args)

       {

               for(String arg: args)

               {

                             System.out.println(arg);

               }

       }

}

在另一个类中调用的方法有

demo.main(new String[ ] { “111”,"222","333"} )

但是当一些场合下 不知道类的名字 无法通过类名调用,这时可以用反射方法解决

//将startname给主函数参数的args[0]

String startname = args[0];

//通过forName获得主函数

Method method = Class.forName(startname).getMethod("main",String [ ] .class);

将三个元素打包成一个数组

method.invoke(null,new Object[ ] (new String[ ] { “111”,"222","333"}));

 

数组的反射应用

如果是一个数组,则依次打印数组的每一个元素 如果是单个字符串直接打印 

class demo

{

       public static void printss(Object obj)

      {

               //得到字节码

               Class example = obj.getClass();

              //通过字节码判断是否是数组 

              if(example.isArray())

               {

                          int len = Array.getLenth(obj);

                          for(int x=0;x<len;x++)

                          {

                                  System.out.println(Array.get(obj,x));

                          }

                }

               else

               {

                      System.out.println(obj);

               }

         }

        public static void main(String [ ] args)

       {

                 //主函数调用

                 String [ ] ass = {"aaa","bbb","ccc"};

                 String   bss = "aaabbbccc" ;

                 printss(ass);

                 printss(bss);

       }

}

                                          第三部分:练习

要求:编写程序,将符合要求的所有对象字符串中的指定字符替换成相应字符

public class filetest

{

        String s1 ="ball";

        String s2 ="basketball";

        String s3 ="itheima";

      public String toString()

        {

            return(s1+":"+s2+":"+"s3");

        }

}

 

import java.text.DateFormat.Field;

class reflect

{

      publicstaticvoid main(String [] args)throws Exception

       {

             filetest pt1 = new filetest();

             changeValue(pt1);

             System.out.print(pt1);

        }

      publicstaticvoid changeValue(Object obj)throws Exception

        {

              java.lang.reflect.Field[] fil = obj.getClass().getFields();

          for(java.lang.reflect.Field field : fil )

             {

                if(field.getType() == String.class)

                     {

                              String oldvalue = (String)field.get(obj);

                              //将b替换成a

                              String newvalue = oldvalue.replace('b','a');

                              fil.set(obj,newvalue);

                     }

             }

       }

}

                                              第四部分:总结

通过前面的学习,反射的应用可以归纳为

(1)修改配置文件,可以通过一个类的其中一个对象 修改所有的对象属性

(2)当程序开发时候,无法知道一些类,不能直接new对象,可以通过反射的方法先写好项目框架

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值