zoukankan      html  css  js  c++  java
  • Java的反射机制(Reflection)

    反射机制

      指可以在运动时加载、探知、使用编译期间完全未知的类

      程序在运行状态中,可以动态加载一个只有名称的类,对于任意一个已加载的类,都能够获取这个类的属性和方法;对于任意一个对象可以调用它的任意一个方法和属性。

      加载完类之后,在堆内存中,就产生一个Class类型的对象(一个类只有一个Class对象),这个对象包含了完整的类的结构信息。我们可以通过这个对象看到类的结构,包括类的属性、类的方法、类的构造函数。

    Class类介绍

      java.lang.Class类十分特殊,用来表示Java中的类型(class/interface/enum/annotation/primitive type/void)本身

      Class对象包含了某个被加载的类的结构。一个被加载的类对应一个Class对象

      Class类是反射的根源,如果想动态加载运行的类,必须先获得相应的Class对象

    Class类的对象如何获取

    1. 运用getClass()

      Student s = new Student();
      s.getClass();
    2. 运用Class.forName() (最常用的方法)

      Class<Student> object = (Class<Student>) Class.forName(className);
    3. 运用.class语法

      Class instance = Student.class;

    反射的常见操作

      1、动态加载类、动态获取类的信息(属性、方法、构造器)

      新建一个Student的类

    package com.parry.guava.reflection;
    
    public class Student {
    
        private String id;
        
        private String name;
        
        private int age;
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public Student(String id, String name, int age) {
            super();
            this.id = id;
            this.name = name;
            this.age = age;
        }
    
        public Student() {
            super();
        }
    
        @Override
        public String toString() {
            return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
        }
        
    }
    Student

      测试动态获取类的属性、方法、构造器

    public class TestReflection {
    
        private final static String className = "com.parry.guava.reflection.Student";
    
        public static void main(String[] args) throws Exception {
            Class<Student> object = (Class<Student>) Class.forName(className);
    
            // 获得包名+类名
            System.out.println("全类名:" + object.getName());
            // 获得类名
            System.out.println("类名" + object.getSimpleName());
    
            // 只能获取public类型的属性
            Field[] fields1 = object.getFields();
            for (Field f : fields1) {
                System.out.println(f);
            }
            // 获取所有类型的属性
            Field[] fields2 = object.getDeclaredFields();
            for (Field f : fields2) {
                System.out.println("类的属性:" + f);
            }
            // 获取指定的任意类型的属性
            Field field1 = object.getDeclaredField("age");
            System.out.println("Point:"+field1);
            // 获取指定的公有的属性
    //        Field field2 = object.getField("age");
    //        System.out.println("Point:"+field2);
            
            // 获取无参构造函数
            Constructor<Student> constructor1 = object.getConstructor(null);
            System.out.println("无参构造函数:" + constructor1);
            //获取含参构造函数
            Constructor<Student> constructor2 = object.getConstructor(String.class, String.class, int.class);
            System.out.println("含参构造函数:" + constructor2);
            
            // 获取公有的方法
            Method[] methods1 = object.getMethods();
            for(Method method:methods1){
                System.out.println("公有的方法:"+ method);
            }
            // 获取所有的方法
            Method[] methods2 = object.getMethods();
            for(Method method:methods2){
                System.out.println("所有的方法:"+ method);
            }
            // 获取指定方法名的方法
        }
    }
    View Code

      2、动态构建对象

        private final static String className = "com.parry.guava.reflection.Student";
    
        public static void main(String[] args) throws Exception {
            Class<Student> object = (Class<Student>) Class.forName(className);
            //通过调用反射API调用构造方法,构建对象
            Student student = object.newInstance(); //其实就是调用了Student的无参构造方法(所以必须保证Student这个JavaBean有无参构造函数)
            System.out.println(student);
        }
    View Code

      3、动态调用类和对象的方法和构造器

      (1)动态调用构造器

        private final static String className = "com.parry.guava.reflection.Student";
    
        public static void main(String[] args) throws Exception {
            Class<Student> object = (Class<Student>) Class.forName(className);
            Constructor<Student> c = object.getConstructor(String.class,String.class,int.class);
            Student s = c.newInstance("1001","parry",18);
            System.out.println(s);
        }
    View Code

      (2)动态调用对象的方法

        private final static String className = "com.parry.guava.reflection.Student";
    
        public static void main(String[] args) throws Exception {
            Class<Student> object = (Class<Student>) Class.forName(className);
            Student student = object.newInstance();
            //通过反射API调用普通方法
            Method method = object.getDeclaredMethod("setName", String.class);
            method.invoke(student, "yang");
            System.out.println(student);
        }
    View Code

      4、动态调用和处理属性

        private final static String className = "com.parry.guava.reflection.Student";
    
        public static void main(String[] args) throws Exception {
            Class<Student> object = (Class<Student>) Class.forName(className);
            Student student = object.newInstance();
            //通过反射API操作属性
            Field field = object.getDeclaredField("name");
            //由于该属性是private,需要声明该属性不做安全检查,直接访问
            field.setAccessible(true);
            field.set(student, "parry");
            System.out.println(student);
        }
    View Code

      

      

  • 相关阅读:
    ubuntu18.04安装ssh服务
    跳转
    【WinForm】—窗体之间传值的几种方式
    使用jQuery完成复选框的全选和全不选
    VS2015下载安装随笔记录
    关于c#数据类型,类型转换,变量,常量,转义符。
    浅谈表单同步提交和异步提交
    form表单提交和跳转
    2019年8月19日矩阵
    C# WinForm快捷键设置技巧
  • 原文地址:https://www.cnblogs.com/parryyang/p/5890189.html
Copyright © 2011-2022 走看看