您的位置:首页 > 职场人生

黑马程序员----反射

2015-09-13 21:28 399 查看
                                                                           第一部分

基础知识篇:

反射的定义:反射就是把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对象,可以通过反射的方法先写好项目框架

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  反射