【数据结构】反射_数据结构

导读:本篇文章讲解 【数据结构】反射_数据结构,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

反射的理解

  1. 反射机制(reflection)
    Java的反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任何一个对象,都能调用它的任意方法和属性,既然可以拿到,那就可以修改部分类型信息;这种动态获取信息以及动态调用方法的功能称为Java语言的反射机制

  2. 应用
    <1>. 反射最重要的作用是开发各种通用的框架

    <2>. 在日常的第三方应用开发的过程中,经常遇到某个类的某个成员变量、方法或是私有的或是只对系统应用开发的,这时候就可以用Java反射机制获取私有成员或方法

    <3>. 反射基本信息
    Java程序中许多对象运行时会有两种类型:

    运行时类型和编译时类型

    程序运行本质是在运行时发现对象的类的真实信息,通过反射机制可以判断出该对象和类属于那些类

反射相关的类

类名 用途
Class类 代表类的实体,在运行Java应用程序中表示类的接口
Field类 代表类的成员变量/类的属性
Method类 代表类的方法
Constructor类 代表类的构造方法

Class类中的相关方法

在这里插入图片描述1. 常用获得类相关的方法

方法 用途
getClassLoader() 获得类的加载器
getDeclaredClasses() 返回一个数组,数组中包含该类中所有类和接口类的对象(包括私有)
forName(String className) 根据类名返回类的对象
newInstance() 创建类的实例
getName() 获得类的完整路径名字
  1. 常用获得类中属性相关的方法(返回值为Field相关)
方法 用途
getField(String name) 获得某个公有的属性对象
getFields() 获得所有公有的属性对象
getDeclaredField(String name) 获得某个属性对象
getDeclaredFields() 获得所有属性对象
  1. 获取类中的构造器相关的方法(返回值为Constructor相关)
方法 用途
getConstructor(Class…<?>parameter Types) 获得该类中与参数类型匹配的公有构造方法
getConstructors() 获得该类的所有公有构造方法
getDeclaredConstructor(Class…<?> parameterTypes) 获得该类中与参数类型匹配的构造方法
getDeclaredConstructors() 获得该类所有构造方法
  1. 获得类中方法 相关的方法(返回值为Method相关)
方法 用途
getMethod(String name, Class…<?> parameterTypes) 获得该类某个公有的方法
getMethods() 获得该类所有公有的方法
getDeclaredMethod(String name, Class…<?> parameterTypes) 获得该类某个方法
getDeclaredMethods() 获得该类所有方法

反射使用

(1)获得Class对象的三种方式

public static void main(String[] args) throws ClassNotFoundException {
        //1.通过Class对象的forName()静态方法获取(用的最多,注意抛异常)
        Class<?> c1 = Class.forName("reflectdemo.Student");

        
    }
    //2.通过getClass获取class对象
    Student student = new Student();
    Class<?> c2 = student.getClass();
    
    //3.直接通过 类型.class获取(更安全可靠,程序性能更高)
    Class<?> c3 = Student.class;

(2)反射的使用——所有和反射相关的包都在 import.java.lang.reefelect包下

//1 通过反射创建对象
    public static void reflectNewInstance() {
        try {
            Class<?> c1 = Class.forName("reflectdemo.Student");
            Student student = (Student) c1.newInstance();

            System.out.println(student);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
 //2 反射私有的构造方法,屏蔽内容为获得公有的构造方法
    public static void reflectPrivateConstructor() {
        try {
            Class<?> c1 = Class.forName("reflectdemo.Student");
            //注意传入对应的参数
            Constructor<?> constructor =
                    c1.getDeclaredConstructor(String.class, int.class);
            //你确定要在类外访问私有方法吗.设置为true后可修改访问权限
            constructor.setAccessible(true);

            Student student = (Student) constructor.newInstance("xiangyu",22);
            System.out.println(student);

        } catch (ClassNotFoundException e) {

        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
//3.反射私有属性
    public static void reflectPrivateField() {
        try {
            Class<?> c1 = Class.forName("reflectdemo.Student");
            Student student = (Student) c1.newInstance();
            //可以修改该属性的值
            Field field = c1.getDeclaredField("name");
            //访问私有的,提前询问一下是否确定访问
            field.setAccessible(true);
            field.set(student,"liubang");
            System.out.println(student);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }


    //4. 反射私有方法
    public static void reflectPrivateMethod() {
        try {
            Class<?> c1 = Class.forName("reflectdemo.Student");
            Student student = (Student) c1.newInstance();

            Method method = c1.getDeclaredMethod("function", String.class);
            method.setAccessible(true);

            method.invoke(student,"通过反射给你传参");

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }//3.反射私有属性
    public static void reflectPrivateField() {
        try {
            Class<?> c1 = Class.forName("reflectdemo.Student");
            Student student = (Student) c1.newInstance();
            //可以修改该属性的值
            Field field = c1.getDeclaredField("name");
            //访问私有的,提前询问一下是否确定访问
            field.setAccessible(true);
            field.set(student,"liubang");
            System.out.println(student);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }


    //4. 反射私有方法
    public static void reflectPrivateMethod() {
        try {
            Class<?> c1 = Class.forName("reflectdemo.Student");
            Student student = (Student) c1.newInstance();

            Method method = c1.getDeclaredMethod("function", String.class);
            method.setAccessible(true);

            method.invoke(student,"通过反射给你传参");

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

反射优缺点

优点:

  1. 任意一个类,都可以知道这个类的所有属性和方法;任意一个对象,都可以调用它的任意一个方法
  2. 增加程序的灵活性和拓展性,降低耦合,提高自适应能力
  3. 反射应用在好多框架上

缺点:

  1. 反射因调用好多方法,可能存在效率降低的问题
  2. 反射技术绕过了源代码的技术,会有维护的问题,并且反射代码比相应直接代码更加复杂

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/119556.html

(0)
seven_的头像seven_bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!