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

      

      

  • 相关阅读:
    【Lintcode】112.Remove Duplicates from Sorted List
    【Lintcode】087.Remove Node in Binary Search Tree
    【Lintcode】011.Search Range in Binary Search Tree
    【Lintcode】095.Validate Binary Search Tree
    【Lintcode】069.Binary Tree Level Order Traversal
    【Lintcode】088.Lowest Common Ancestor
    【Lintcode】094.Binary Tree Maximum Path Sum
    【算法总结】二叉树
    库(静态库和动态库)
    从尾到头打印链表
  • 原文地址:https://www.cnblogs.com/parryyang/p/5890189.html
Copyright © 2011-2022 走看看