美文网首页
java 反射机制及动态代理

java 反射机制及动态代理

作者: nade_s | 来源:发表于2018-07-17 16:27 被阅读0次

    反射概述
    Reflection(反射)是Java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的內部信息,并能直接操作任意对象的内部属性及方法。

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

    在运行时构造任意一个类的对象
    在运行时获取任意一个类所具有的成员变量和方法
    在运行时调用任意一个对象的方法(属性)
    生成动态代理

    Class 是一个类; 一个描述类的类.
       封装了描述方法的 Method,
    描述字段的 Filed,
    描述构造器的 Constructor 等属性.
    下面我们以student为例 一一介绍

    先说获取Class对象的三种方式
    1.通过类名获取 类名.class
    2.通过对象获取 对象名.getClass()
    3.通过全类名获取 Class.forName(全类名)

       //类名.class
        Class<ConStudent> conSC = ConStudent.class;
        System.out.print("---------类名.class---------"+"\n");
        //对象名.getClass()
        ConStudent conStudent = new ConStudent();
        Class<? extends ConStudent> conSC1 = conStudent.getClass();
        System.out.print("---------对象名.getClass()---------"+"\n");
        //Class.forName(全类名)
        Class<?> conSC2 = Class.forName("com.reflection.ConStudent");
        System.out.print("---------Class.forName(全类名)---------");
    

    ---------类名.class---------
    静态代码:10
    ---------对象名.getClass()---------
    静态代码:10
    ---------Class.forName(全类名)---------

    public class ConStudent {

    public static int number = 10;
    static {
        System.out.print("静态代码:"+number+"\n");
    }
    

    }

    通过以上方式可以看出 第二第三种方式是直接调用静态代码的 从方便和效率来看 第三中方式是最好的 第一种也不错 第二种是不推荐的 个人建议 仅供参考

    现在说一下 Constructor

    先看一下 实体类

    /**

    • Constructor
      */
      public class ConStudent {

      public ConStudent(){
      System.out.print("ConStudent空参构造函数"+"\n");
      }

      public ConStudent(double score) {
      System.out.print("ConStudent有参构造函数"+"\n");
      }

      private ConStudent(int age) {
      System.out.print("ConStudent私有构造带参数"+age+"\n");
      }
      protected ConStudent(String name){
      System.out.print("ConStudent受保护的构造参数"+name+"\n");
      }

    }
    private static void constructor() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

        Class<?> conSC = Class.forName("com.reflection.ConStudent");
        Constructor<?>[] constructors = conSC.getConstructors();
        for (Constructor c :constructors){
            System.out.print("ReflectTest所有公有构造:"+c+"\n");
        }
        System.out.print("ReflectTest----------分割线-------------"+"\n");
    
        Constructor<?>[] declaredConstructors = conSC.getDeclaredConstructors();
        for (Constructor c : declaredConstructors){
    
            System.out.print("ReflectTest所有构造方法:"+c+"\n");
        }
        System.out.print("ReflectTest----------分割线-------------"+"\n");
        Constructor constructor = conSC.getConstructor();
        System.out.print("ReflectTest公有无参构造方法"+constructor+"\n");
        System.out.print("ReflectTest----------分割线-------------"+"\n");
        Constructor<?> declaredConstructor = conSC.getDeclaredConstructor(int.class);
        System.out.print("ReflectTest私有构造方法"+declaredConstructor+"\n");
        declaredConstructor.setAccessible(true);
        Object o = declaredConstructor.newInstance(11);
        System.out.print("ReflectTest调用私有构造"+o+"\n");
        System.out.print("ReflectTest----------分割线-------------"+"\n");
        Constructor<?> declaredConstructor1 = conSC.getDeclaredConstructor(String.class);
        declaredConstructor1.setAccessible(true);
        Object maoge = declaredConstructor1.newInstance("maoge");
        System.out.print("ReflectTest受保护的构造:"+maoge);
    
    }
    

    输出内容

    ReflectTest所有公有构造:public com.reflection.ConStudent(double)
    ReflectTest所有公有构造:public com.reflection.ConStudent()
    ReflectTest----------分割线-------------
    ReflectTest所有构造方法:protected com.reflection.ConStudent(java.lang.String)
    ReflectTest所有构造方法:private com.reflection.ConStudent(int)
    ReflectTest所有构造方法:public com.reflection.ConStudent(double)
    ReflectTest所有构造方法:public com.reflection.ConStudent()
    ReflectTest----------分割线-------------
    ReflectTest公有无参构造方法public com.reflection.ConStudent()
    ReflectTest----------分割线-------------
    ReflectTest私有构造方法private com.reflection.ConStudent(int)
    ConStudent私有构造带参数11
    ReflectTest调用私有构造com.reflection.ConStudent@14ae5a5
    ReflectTest----------分割线-------------
    ConStudent受保护的构造参数maoge
    ReflectTest受保护的构造:com.reflection.ConStudent@7f31245a
    Process finished with exit code 0

    下面看一下 Filed
    实体也是三个参数 代表三种权限

    /**

    • Filed
      */
      public class FiledStudent {
      public int age;
      private String name;
      protected double score;

      @Override
      public String toString() {
      return "FiledStudent{" +
      "age=" + age +
      ", name='" + name + ''' +
      ", score=" + score +
      '}';
      }

      public int getAge() {
      return age;
      }

      public void setAge(int age) {
      this.age = age;
      }

      public String getName() {
      return name;
      }

      public void setName(String name) {
      this.name = name;
      }

      public double getScore() {
      return score;
      }

      public void setScore(double score) {
      this.score = score;
      }
      }

    private static void filedTest() throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
    Class<?> filedSC = Class.forName("com.reflection.FiledStudent");
    Field[] fields = filedSC.getFields();
    for (Field f :fields){
    System.out.print("ReflectTest所有公有的参数:"+f+"\n");
    }
    System.out.print("ReflectTest----------分割线-------------"+"\n");
    Field age = filedSC.getField("age");
    Object o = filedSC.getConstructor().newInstance();
    age.set(o,11);
    FiledStudent student = (FiledStudent) o;
    System.out.print("ReflectTest获取公有参数:"+student.getAge()+"\n");
    System.out.print("ReflectTest----------分割线-------------"+"\n");
    Field[] declaredFields = filedSC.getDeclaredFields();
    for (Field f :declaredFields){
    System.out.print("ReflectTest获取所有参数:"+f+"\n");
    }
    System.out.print("ReflectTest----------分割线-------------"+"\n");
    Field name = filedSC.getDeclaredField("name");
    name.setAccessible(true);
    name.set(o,"Maoge");

        System.out.print("ReflectTest获取指定的私有参数:"+student.getName()+"\n");
        System.out.print("ReflectTest----------分割线-------------"+"\n");
        Field score = filedSC.getDeclaredField("score");
        score.setAccessible(true);
        score.set(o,9.8);
        System.out.print("ReflectTest获取受保护的参数:"+student.getScore());
    
    }
    

    下面看 mothed

    /**

    • Method
      */
      public class MethodStudent{
      int age;
      String name;
      double score;

      public void showName( ){
      System.out.print("(公共)姓名:");
      }
      private void showAge(){
      System.out.print("(私有)年龄:");
      }
      protected void showScore(){
      System.out.print("(保护)分数:");
      }

      public String printName(String name){
      System.out.print("(公共string)name:"+name);
      return name;
      }
      private double printScore(double score){
      System.out.print("(私有double)score:"+score);
      return score;
      }
      protected int printAge(int age){
      System.out.print("(保护age)age:"+age);
      return age;
      }

    }

    private static void methodTest() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
    Class<?> methodSC = Class.forName("com.reflection.MethodStudent");
    Method[] declaredMethods = methodSC.getDeclaredMethods();
    for (Method m : declaredMethods){
    System.out.print("ReflectTest 获取所有的方法:"+m+"\n");
    }
    System.out.print("ReflectTest----------分割线-------------"+"\n");
    Method[] methods = methodSC.getMethods();
    for (Method m : methods){
    System.out.print("ReflectTest获取所有的公有方法"+m+"\n");
    }
    System.out.print("ReflectTest----------分割线-------------"+"\n");
    Method score = methodSC.getDeclaredMethod("printScore", double.class);
    Object o = methodSC.getConstructor().newInstance();
    score.setAccessible(true);
    Object invoke = score.invoke(o, 9.8);
    System.out.print("ReflectTest调用制定的私有方法:"+invoke+"\n");
    System.out.print("ReflectTest----------分割线-------------"+"\n");

        Method printName = methodSC.getMethod("printName", String.class);
        Object maoge = printName.invoke(o, "Maoge");
        System.out.print("ReflectTest公有有参数方法:"+maoge+"\n");
        System.out.print("ReflectTest----------分割线-------------"+"\n");
        Method showName = methodSC.getMethod("showName", null);
        System.out.print("ReflectTest公有无参方法:"+showName+"\n");
        System.out.print("ReflectTest----------分割线-------------"+"\n");
        Method printAge = methodSC.getDeclaredMethod("printAge", int.class);
        printAge.setAccessible(true);
        Object invoke1 = printAge.invoke(o, 20);
        System.out.print("ReflectTest受保护的方法:"+invoke1);
    }
    

    这是反射的一些基础使用

    下面说一下动态代理 (代理可以让我们的方法或者类进行功能扩展 解耦等好处)

    新建一个接口

    public interface Person {
    void work();
    }

    新建一个接口实现类(被角色代理)

    public class PersonImpl implements Person{

    @Override
    public void work() {
        System.out.print("i am PersonImpl.calss");
    
    }
    

    }

    新建一个代理角色

    public class PersonHandler implements InvocationHandler {
    public Object px;

    public PersonHandler(Object px) {
        this.px = px;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.print("do work"+"\n");
        return method.invoke(px,args);
    }
    

    }

    绑定代理

    public class PersonProxyTest {
    public static void main(String[] args) {
    Person person = new PersonImpl();
    Person o = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class[]{Person.class}, new PersonHandler(person));
    o.work();
    }

    }

    好了 本文到此结束 欢迎留言或私信

    相关文章

      网友评论

          本文标题:java 反射机制及动态代理

          本文链接:https://www.haomeiwen.com/subject/gabwpftx.html