zoukankan      html  css  js  c++  java
  • 反射机制

    反射:

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

    反射:通过字节码文件对象,使用该对象来获取一个类的所有信息。(列如:成员方法、成员变量、构造方法、静态方法、常量、访问权限修饰符、泛型...包括私有)

    反射之前做法:

    Student s = new Student()

    反射之后:

    1、获取到学生类对应的字节码文件对象

    2、通过字节码文件对象获取构造方法对象

    3、通过构造方法对象创建对象

    反射的 好处:

    1、使得代码的可维护性和扩展性提高

    2、反射是框架的核心

    如何来获取字节码文件对象?

    方式一:

    通过Class 类中 getClass()方法,但是此方法的缺点是必须创建对象才能够调用getClass()方法。

    方式二:

    通过数据类型的class 属性创建,缺点是需要显示声明 XXX类,优点是创建方便。

    注:凡是一个方法的 形参希望们转入的是Class类型,推荐使用第二种方式

    public void method(Class c) {

    }

    method(XXX.class);

    方式三:

    通过Class类中的一个方法Class.forName(类名的全路径)。

    优点:不需要显示编写XXX类,满足了开闭原则,提高了代码的可维护性。

    public class Student01 {
    ​
    public static void main(String[] args) throws ClassNotFoundException {
    //方式一:通过get.Class()方法来获取
    Student s = new Student();
    Class<?> c1 = s.getClass();
    System.out.println(c1);
    ​
    //方式二:通过数据类型的属性class类创建来获取
    Class<Student> c2 = Student.class;
    System.err.println(c1 == c2);
    ​
    //方式三;通过Class.forName(类名路径)方法
    Class<?> c3 = Class.forName("com.sxt.sext.Student");
    System.out.println(c1 == c3);
    •   }
    }

    方式三还可以把路径名直接写到文件,直接在文件里面修改类就可以了,满足了开闭原则,提高了代码的可维护性。如下代码展示

     
    //通过Class.forName(类名路径)方法
            Properties pr = new Properties();
            pr.load(new FoleReader("com.sxt.sext.Student"));
            String className = pr.getProperty("className")
            Class<?> c3 = Class.forName(className);
            System.out.println(c3);
            System.out.println(c1 == c3);
    
    
    
     

    Class的作用用于判断一个运行时对象的类型如下:

    public static void test1(Object obj){
    ​
    Class cls = Student.class;
    ​
    if(cls.isInstance(obj)){
    ​
    •   }
    ​
    }

    让一个对Student对象可以与String和Integer进行比较如下:

    
    
    public boolean equals(Object obj){
    ​
    // 与一个String对象比较
    if(String.class.isInstance(obj)){
    ​
    String other = (String)obj;
    ​
    return other.equals(this.name);
    ​
    }
    
    
    


    // 与一个Integer对象比较

    if(Integer.class.isInstance(obj)){
    ​
    Integer other = (Integer)obj;
    ​
    return this.id == other;
    ​
    }
    ​
    return false;
    ​
    }
    
    
    
     

    通过Reflection机制,我们可以直接从class文件反推出它有哪个成员变量、有哪些函数。

    遍历Method 已知函数名,找到对象的 Method

    Class cls = …
    ​
    String methodName = "setId";
    ​
    // 获取所有Method列表,顺序比对
    ​
    Method[] methods = cls.getMethods();
    ​
    for(Method m : methods){
    ​
    if(m.getName().equals(methodName)){
    ​
    break;
    ​
    }
    ​
    }

     

    查找Method 已知函数名,参数列表,寻找Method如下:

    Class cls = …
    ​
    String methodName = "setId";
    ​
    Class[] parameterTypes = { int.class };
    ​
    Method m = cls.getMethod(methodName, 
    ​
     parameterTypes);

     

  • 相关阅读:
    Docker-CentOS系统安装Docker
    Docker-准备Docker环境
    Docker系列-文章汇总
    商品订单库存一致性问题的思考
    java模板、工厂设计模式在项目中的重构
    2018Java年底总结
    java的AQS中enp没有同步代码块为啥是原子操作
    java使用awt包在生产环境docker部署时出现中文乱码的处理
    初探装饰器模式
    开灯问题
  • 原文地址:https://www.cnblogs.com/qinchangchuan/p/10828016.html
Copyright © 2011-2022 走看看