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

    反射的功能

    API简介

    方法介绍

    获取Class的三种方式

    生成对象

    反射访问私有(private)的方法

    反射机制的优点与缺点

    JAVA反射机制是在运行状态中,动态获取的类的所有信息以及动态调用对象的方法(或属性),称为java语言的反射机制。

    注意:反射是在运行的时候进行的,不是在编译的时候运行的。

    反射的功能

    Java反射机制主要提供了以下功能

    • 在运行时判断任意一个对象所属的类;
    • 在运行时构造任意一个类的对象;
    • 在运行时判断任意一个类所具有的成员变量和方法;
    • 在运行时调用任意一个对象的方法;生成动态代理。

    API简介

    在这里先看一下sun为我们提供了那些反射机制中的类:

      — java.lang.Class;        代表一个类

      — java.lang.reflect.Constructor; 代表类的构造方法 

      — java.lang.reflect.Field;        代表类的成员变量(成员变量也称为类的属性)

      — java.lang.reflect.Method;  代表类的方法

      — java.lang.reflect.Array;  提供了动态创建数组,以及访问数组的元素的静态方法

    注意:java中无论生成某个类的多少对象, 这些对象都会对应于同一个Class对象。

    方法介绍

    方法关键字 含义
    getDeclaredMethods() 获取所有的方法
    getReturnType() 获得方法的放回类型
    getParameterTypes() 获得方法的传入参数类型
    getDeclaredMethod("方法名",参数类型.class,……) 获得特定的方法
       
    构造方法关键字 含义
    getDeclaredConstructors() 获取所有的构造方法
    getDeclaredConstructor(参数类型.class,……) 获取特定的构造方法
       
    父类和父接口 含义
    getSuperclass() 获取某类的父类
    getInterfaces() 获取某类实现的接口

    获取Class的三种方式

    1)使用Class类的forName(String className)静态方法。改方法需要传入字符串参数,改字符串参数的值是某个类的全限定类名(必须添加完整的包名)。

    Class.forName("java.lang.String");

    2)调用某个的class属性来获取该类对应的class对象,如

    String.class

    3)调用某个对象的getClass方法。

    String s = "aa";
    Class<?> clazz = s.getClass();

    生成对象

    1)通过不带参数的构造方法生成对象有两种方法

      a)先获得Class对象,然后通过该Class对象的newInstance()方法直接生成即可:

      newInstance()方法可以返回一个实例,但是构造方法要是没有参数列表的,它相当于调用某个类的不带参数的构造方法,但是如果在初始化对象的时候要传参数,就要使用Constructor

    Class<?> classType = String.class;
    Object obj = classType.newInstance(); 

      b)先获得Class对象,然后通过该对象获得相应的Constructor对象,再通过该Constructor对象的newInstance()方法生成:

    Class<?> classType = object.getClass();
    Constructor cons = classType.getConstructor(new Class[]{});
    Object obj = cons.newInstance(new Object[]{});

    2)若想通过类的带参数的构造方法生成对象,只能使用下面一种方式

       Class<?> classType = object.getClass();
       Constructor cons = classType.getConstructor(new Class[]{String.class,int.class});
       Object obj = cons.newInstance(new Object[]{"hello",3});
       //以上的两行代码等价于下面一行
       //Object obj2 = classType.newInstance();

    反射访问私有(private)的方法

      private 限制的方法没有办法在另外的类中使用,但可以使用反射进行使用。而getMethod()方法只能获取public的方法。如果要使用private的方法就要使用 getDeclaredMethod()方法。

    1、获取privete方法

    public class PrivateTest {
        private String sayHello(String name){
          return "hello" + name;
       }
    }
    public class Test{
      public static void main(String[] args) throws Exception{
    
        PrivateTest obj = new PrivateTest();
        Class<?> classType = obj.getClass();
        Method method = classType.getDeclaredMethod("sayHello", new Class[]{String.class});
        method.setAccessible(true);       //压制java的访问控制检查
        String str = (String)method.invoke(obj, new Object[]{"aaa"});
    
      }
    }

    2、改变private的属性

    public class PrivateTest2 {
       private String name = "张三";
       public String getName(){
          return name;
       }
    }
    public class Test{
       public static void main(String[] args) throws Exception{
    
        PrivateTest2 obj = new PrivateTest2();
        Class<?> classType = obj.getClass();
        Field field = classType.getDeclaredField("name");
        field.setAccessible(true);
        field.set(obj, "李四");
        System.out.println(obj.getName());
       }
    }

     反射机制的优点与缺点

    为什么要用反射机制?直接创建对象不就可以了吗,这就涉及到了动态与静态的概念。

    • 静态编译:在编译时确定类型,绑定对象,即通过。
    • 动态编译:运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,有以降低类之间的藕合性。  

      优点——可以实现动态创建对象和编译,体现出很大的灵活性,特别是在J2EE的开发中。

      比如,一个大型的软件,不可能一次就把把它设计的很完美,当这个程序编译后,发布了,当发现需要更新某些功能时,我们不可能要用户把以前的卸载,再重新安装新的版本,假如这样的话,这个软件肯定是没有多少人用的。采用静态的话,需要把整个程序重新编译一次才可以实现功能的更新,而采用反射机制的话,它就可以不用卸载,只需要在运行时才动态的创建和编译,就可以实现该功能。

      缺点——对性能有影响。

      使用反射基本上是一种解释操作,这类操作总是慢于只直接执行相同的操作。

     

  • 相关阅读:
    CentOS7搭建elasticsearch集群
    Centos7搭建redis集群及安装sentinel
    编译安装haproxy开启支持SSL
    CentOS7单节点部署redis主从复制和sentinel
    CentOS7单节点部署redis-cluster
    搭建hadoop集群
    配置nginx为FastDFS的storage server提供http访问接口
    FastDFS分布式存储
    一键部署Kubernetes高可用集群
    一键部署ETCD集群脚本
  • 原文地址:https://www.cnblogs.com/sweetyu/p/5032396.html
Copyright © 2011-2022 走看看