黑马程序员——关于反射技术

来源:互联网 发布:csgo 性能数据 编辑:程序博客网 时间:2024/06/05 20:14

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

 

反射类用于制作框架中。有了反射,在配置文件中写的代码才能被解析。

通过反射有三种方法可以加载类:

1Classclazz=Class.forName("cn.itcast.reflect.Person");

Class类代表某个类的字节码,调用forName方法,加载某个类,返回某个类的字节码;

这句代码执行,就是把硬盘上的Person类加载到了内存中并采用Class类进行封装成为字节码

2Class clazz1=new Person().getClass();

3Class clazz2=Person.class;

由于一个类有多个组成部分,例如:成员变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分。

 

一、解剖反射类的构造函数,创建类的对象。

下面是对于Person类的各种构造函数进行反射的代码:

1、对于公共的无参构造函数public Person(),实现代码如下:

Classclazz=Class.forName("cn.itcast.reflect.Person");//获取类的字节码对象

Constructorc=clazz.getConstructor(null);//获取构造函数对象,参数类型为null

Person p=(Person)c.newInstance(null);//初始化对象,传入的参数是null

 

2、对于公共的有参构造函数public Person(String name),实现代码如下:

Classclazz=Class.forName("cn.itcast.reflect.Person");

Constructorc=clazz.getConstructor(String.class);//参数类型为String.class

Person p=(Person)c.newInstance("abc");//初始化对象,传入参数是String类型即可

 

    3、对于公共的多参构造函数public Person(String name,intpassword),实现代码如下:

    Classclazz=Class.forName("cn.itcast.reflect.Person");

   //参数类型为String.class,int.class

    Constructorc=clazz.getConstructor(String.class,int.class);

   //初始化对象,传入参数对应构造函数即可

    Personp=(Person) c.newInstance("abc",999);

        

    4、对于私有构造函数private Person(List list),实现代码如下:

    Class clazz=Class.forName("cn.itcast.reflect.Person");

     //使用的是getDeclaredConstructor()方法。

     Constructorc=clazz.getDeclaredConstructor(List.class);

     c.setAccessible(true);//暴力反射,强制打开访问权限

     Personp=(Person) c.newInstance(new ArrayList());

 

    5、创建对象的另外一种途径,无参构造方法,等效于1

     Classclazz=Class.forName("cn.itcast.reflect.Person");

     Personp=(Person) clazz.newInstance();

 

二、解剖反射类的方法

下面是对于Person类的各种方法进行反射的代码:

1、 对于公共无参并且无返回值的方法publicvoid test(),实现代码如下:

 

Class clazz =Class.forName("cn.itcast.reflect.Person");

//第一个参数是方法名,第二个是传入的参数类型,将test方法传入Method对象中

Method method =clazz.getMethod("test", null);

Person p = newPerson();//创建person对象

method.invoke(p,null);//执行方法,第一个参数要指定是哪个对象执行的方法

 

2、 对于公共有参并且无返回值的方法publicvoid test (String name,int password),实现代码如下:

 

Class clazz =Class.forName("cn.itcast.reflect.Person");

//同样,第一个参数是方法名,后面的参数按照方法定义的顺序写

Method method =clazz.getMethod("test ", String.class,int.class);

Person p = newPerson();

method.invoke(p,"abc",1111);//执行方法

 

3、 对于公共有参返回类型为数组的方法publicClass[] test(String name,int[] password),实现代码如下:

 

Class clazz =Class.forName("cn.itcast.reflect.Person");

Method method = clazz.getMethod("test ",String.class,int[].class);

Person p = new Person();

//将返回数据传给cs Class类数组中

Class cs[] = (Class[]) method.invoke(p, "abc",newint[]{1,2,3});

 

4、 对于私有方法private voidtest(InputStream in),实现代码如下:

 

Class clazz =Class.forName("cn.itcast.reflect.Person");

//私有方法使用的是getDeclaredMethod方法。

Method method =clazz.getDeclaredMethod("test ",InputStream.class);

method.setAccessible(true);//暴力反射,强制打开访问权限

Person p = newPerson();

method.invoke(p,newFileInputStream("C:\\1.txt"));

 

5、 对于静态方法public static voidtest(int num),实现代码如下:

 

Class clazz =Class.forName("cn.itcast.reflect.Person");

Method method =clazz.getMethod("test",int.class);

method.invoke(null,777);//静态方法调用不需要对象,不过给对象也可以

 

6、 对于如main方法一样的传入参数是字符串数组的方法public static void main(String[]args),实现代码如下:

 

Class clazz =Class.forName("cn.itcast.reflect.Person");

Method method =clazz.getMethod("main",String [].class);

 

String []str ={"x","y","z"};

method.invoke(null,(Object)str);//String数组转化为Object类,就可以运行

 

三、解剖反射类的字段

        

1、 对于公共字段public Stringname来说,实现代码如下:

 

public void test1() throwsException{

        Classclazz=Class.forName("cn.itcast.reflect.Person");

        Fieldf=clazz.getField("name");//获取name字段的值存入Field对象中

        Personp=new Person();          

        Objectvalue= f.get(p);//获取字段值

        Classtype=f.getType();//字段类型

        //设置值,将获取到的name字段进行设置值,第一个参数为对象p

        f.set(p,"ppppp");

    }

 

2、对于私有字段private int password来说,实现代码如下:

        

    publicvoid test2() throws Exception{

          Classclazz=Class.forName("cn.itcast.reflect.Person");

          //获取password字段的值存入Field对象中,使用的是getDeclaredField方法

          Fieldf=clazz.getDeclaredField("password");

          f.setAccessible(true);//暴力反射,强制打开访问权限

          Personp=new Person();

          f.set(p,123);//设置值

     }

 

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

 详细请查看:http://edu.csdn.net