zoukankan      html  css  js  c++  java
  • 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创建的对象用反射来实现,这样就可以通过配置文件等来管理整个项目而不需要修改代码。

  • 相关阅读:
    基于element-ui图片封装组件
    计算时间间隔具体每一天
    C语言学习笔记 —— 函数作为参数
    AtCoder Beginner Contest 049 题解
    AtCoder Beginner Contest 048 题解
    AtCoder Beginner Contest 047 题解
    AtCoder Beginner Contest 046 题解
    AtCoder Beginner Contest 045 题解
    AtCoder Beginner Contest 044 题解
    AtCoder Beginner Contest 043 题解
  • 原文地址:https://www.cnblogs.com/clownice/p/5334646.html
Copyright © 2011-2022 走看看