Java学习之反射

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。

Java反射机制提供的功能

在运行时判断任意一个对象所属的类

在运行时构造任意一个类的对象

在运行时判段任意一个类所具有的成员变量和方法

在运行时调用任一个对象的方法

在运行时创建新类对象

在使用Java的反射功能时,基本首先都要获取类的Class对象,再通过Class对象获取其他的对象。

关于反射机制中的使用推荐博客:http://blog.csdn.net/xiaoxian8023/article/details/9206055

Java的反射机制的实现要借助于4个类:class,Constructor,Field,Method;

1 Class c = Class.forName("Triangle");                      //获取Class对象
2 //获取相应参数的构造参数
3 Constructor con = c.getConstructor(long.class,long.class,long.class);
4 //通过相应的构造函数创建对象
5 Object obj = con.newInstance(testcase[0],testcase[1],testcase[2]);
6 //获取相应参数的方法 
7 Method m = c.getDeclaredMethod("getType", c);
m.invoke(obj,obj);

 

关于获取方法的getDeclaredMethod和getMethod的区别

getDeclaredMethod可以获取私有的方法和保护的方法

getMethod只能获得public公有方法,如要访问私有方法,需设置可见性setAccessible(),设置为true就和getDeclaredMethod作用相同。

可是从类的开发要求而言,一直都强调类之中的属性必须封装,所以现在调用之前要想办法解除封装即setAccessible()

packagecn.mldn.demo;
importjava.lang.reflect.Field;
classPerson {
privateString name;
}
publicclassTestDemo {
publicstaticvoidmain(String[] args) throwsException {
Class<?> cls = Class.forName("cn.mldn.demo.Person"); // 取得Class对象
Object obj = cls.newInstance(); // 对象实例化属性才会分配空间
Field nameField = cls.getDeclaredField("name") ; // 找到name属性
nameField.setAccessible(true) ; // 解除封装了
nameField.set(obj, "张三") ; // Person对象.name = "张三"
System.out.println(nameField.get(obj)); // Person对象.name
}
}

相关讨论可见http://www.zhihu.com/question/24304289

package test.reflection;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Person {
    private String name;//私有属性
    public String address;
    public Person(String name){
        this.name=name;
    }
    private void setAddress(String address){ //私有方法
        this.address=address;
    }
    public static void main(String[] args) {
        try{
            Person person=new Person("zhangsan");
            Class<Person> cls=Person.class;
            //获得私有方法
            Method method=cls.getDeclaredMethod("setAddress", new Class[]{String.class});
            //设置私有方法可以被访问
            method.setAccessible(true);
            //调用私有方法
            method.invoke(person, new Object[]{"BJUT"});
            System.out.println(person.address);//输出BJUT
            
            //访问私有变量
            Field field=cls.getDeclaredField("name");
            field.setAccessible(true);
            System.out.println(field.get(person));//输出zhangsan
            
        }catch(Exception ex){
            ex.printStackTrace();
        }
        
    }
}

这种反射机制在框架开发的时候经常用到,比如简单工厂或抽象工厂时,为了降低耦合度,我们需要把用new创建的对象用反射来实现,这样就可以通过配置文件等来管理整个项目而不需要修改代码。

 

posted @ 2016-03-29 20:35  lzt-software  阅读(258)  评论(0编辑  收藏  举报