黑马程序员------反射

来源:互联网 发布:知柏地黄丸感冒能吃吗 编辑:程序博客网 时间:2024/06/03 05:15

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

反射

1.概述

反射就是指在程序运行过程中,通过.class文件动态的获取类的属性,方法,和构造并且使用

但是要注意的是,java只能通过反射实现类的调用,而不能改变类的结构


2.创建Class文件的三种方式

1.通过Class.forName(“类全名”)

2.通过对象的getclass()方法

3.通过类名。class


3.获取构造方法并创建对象

1.获取Class对象

2.通过getDecloaredConstructor(),getConstructor()方法创建构造器对象,如果构造器没有参数写null,

注意,getDecloaredConstructor()可以获取私有方法,通常与setAccessiblie()方法连用

3.通过newInstance(实际参数1, 实际参数2)方法创建对象

例如

1、通过private Person(String name, int age)创建对象
         //通过类全名获取对象内容
 Class clazz =  Class.forName("reflex.Person");
         //获取两个参数的构造方法
Constructor con = clazz.getDeclaredConstructor(String.class, int.class);
//因为方法私有,所以将此方法参数设置为true
          con.setAccessible(true);

//创建对象

          Object obj = con.newInstance("zhangsan",120);


4.获取属性并调用

 1.获取Class对象
     2.通过调用getDeclaredField("属性名")或通过调用getField("属性名") 获取属性管理器
     3.如果获取的是私有的属性,调用setAccessible()方法,并传入参数true
     4.调用属性管理器的set(该类的对象,值) 来设置属性值,调用属性管理器的get(该类的对象)来获取属性值

例如:

Person p1 = new Person();

Person p2 = new Person();

//获取Class对象

Class clazz = Class.forName("person");

//获取属性管理器

Field field = clazzgetDeclaredField("name");

//考虑属性私用,将setAccessible()内设置为true

field.setAccessible(true);

//设置属性值

field.set(p1,"张三");

field.set(p2,"李四");

//获取属性值

Syso(field.get(p1));

Syso(field.get(p2));


5.获取方法并调用

1.获取Class对象

2.通过getDeclaredMethod("方法名",形参1.class...)获取方法

3.考虑到方法私有,需用setAccessible(true)方法

4.通过invoke(该类对象,实参)方法执行方法,没有参数则写null

例如

 Person p1 = new Person("张三",13);
         Person p2= new Person("李四",14);
         Class clazz =  Class.forName("Person");

//调用setName方法

Method.setName =clazz.getDeclaredMethod("setName",String.class);

setName.setAccessible(true);

setName.invoke(p1,"张三三")

//调用getName方法

Method,getName = clazz.getDeclaredMethod("getName",null);

getName.Accessible(true);

syso(getName.invoke(p1,null));

总结:

利用反射虽然可以增加代码的灵活度,是的程序易维护,但是程序中大量使用反射会导致程序效率变慢,所以要适量使用,并且在获取类的内容是,为保证不受私用影响,所以一般使用getDeclaredConstructor(),getDeclaredField(),getDeclaredMethod(),配合setAccessible(true)使用

反射应用

1:通过反射修改成员变量的值,包括私有
2: 通过反射运行配置文件
  在JAVA项目下新建配置文件config,内容为
     class=Person
         name=jack

    代码:
          Properties p = new Properties();
          p.load(new FileReader("config"));
           String className  = (String)p.get("class");
          String name = (String)p.get("name");
         
          Class clazz = Class.forName(className);
           //创建对象
           Constructor constructor = clazz.getConstructor(null);
           Object instance = constructor.newInstance();
         
          //通过setName设置name属性
          Method setName = clazz.getDeclaredMethod("setName", String.class);
           setName.invoke(instance,name );
         
          //通过getName设置name属性
          Method method = clazz.getDeclaredMethod("getName",null);
          Object object = method.invoke(instance, null);
          System.out.println(object);

3: 通过反射给 ArrayList<Integer>中添加String 类型的数据
         ArrayList<Integer> list = new ArrayList<Integer>();
          list.add(123);
         
         
        Class clazz =  Class.forName("java.util.ArrayList");//必须通过类全名获取
        Method method = clazz.getDeclaredMethod("add", Object.class);
        method.setAccessible(true);
        method.invoke(list, "ss");
        
        for(Object obj: list){
             System.out.println(obj);
        }




0 0
原创粉丝点击