首页 > 编程语言 >Java中的反射机制及反射的优缺点

Java中的反射机制及反射的优缺点

时间:2022-12-06 14:45:29浏览次数:48  
标签:反射 Singleton MyObject Java 优缺点 获取 实例 Class

1. 反射的概念

反射 机制指的是,程序在运行时能够获取自身的信息。在 java 中只要给定类的名字,就能够获取类的所有属性和方法

反射是 Java 中很多高级特性的基础,比如 注解、动态代理 以及 Spring Ioc、AOP 等技术都需要借助反射来实现。

2. Class 对象的创建

java 中 java.lang.Class 是反射机制的基础,当我们想要在运行期获取一个类中的相关信息的时候,必须先获取其 Class 类。Jvm 会自动将已加载类的 Class 对像载入。

获取 Class 对象的三种方式:

  • 对象实例.getClass()

    MyObject obj = new MyObject();
    

    Class clazz = obj.getClass();

  • 类名.Class

    Class clazz = MyObject.Class;
    
  • Class.forName()

    Class clazz = Class.forName("MyObject");
    

3. 通过反射创建实例

java 中,最常使用的创建实例方法是通过 new 关键字来实现的。使用反射,也有两种可以 创建实例 的方式。

使用 Class 对象的 newInstance() 方法

Class clazz = MyObject.class;
MyObject myObject = clazz.newInstance();

使用 java.lang.reflet.Constructor 中的 newInstance() 方法

Constructor<MyObject> constructor = MyObject.class.getConstructor();
MyObject myObject = constructor.newInstance();

说明:其实 clazz.newInstance() 创建实例的内部也是通过 Constructor 创建实例的方式来实现的

4. 通过反射获取类的属性、方法、注解、构造器

Class 类中有获取类的所有 属性、方法、注解、构造器的相关方法。如下:

获取 非私有的 属性、方法、注解、构造器

Field[] getFields();    // 获取属性
Method[] getMethods();  // 获取方法
Annotation[] getAnnotations();  // 获取注解
Constructor<?>[] getConstructors();   // 获取构造器

获取** 私有的** 属性、方法、注解、构造器

Field[] getDeclaredFields();    // 获取私有属性
Method[] getDeclaredMethods();  // 获取私有方法
Annotation[] getDeclaredAnnotations();  // 获取私有注解
Constructor<?>[] getDeclaredConstructors();   // 获取私有构造器

使用示例:

Class clazz = MyObject.class;
Methods[] methodList = clazz.getFields();

5. 反射机制的一些缺点

  • 反射会破坏封装性:由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用--代码有功能上的错误,降低可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。

  • 反射的性能问题:反射包括了一些动态类型,所以 JVM 无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。我们应该避免在经常被 执行的代码或对性能要求很高的程序中使用反射。

  • 安全性问题:使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有安全限制的环境中运行,如 Applet,那么这就是个问题了。

6. 反射对单例的破坏

单例是为了控制 类示例 在内存中只存在一个的机制。他本身的构造方法是 private 的,对外提供 getSingleton() 方法,统一管理实例的获取。

而反射可以通过获取到类中的私有构造方法, 并将其变为可用,通过构造方法生成新的实例,这样就造成了单例的破坏。

双重校验锁的单例模式:

public class Singleton {
    private static volatile Singleton singleton();

    private Singleton() {
    }

    public static Singleton getSingleton() {
        if(singleton == null) {
            synchronized (Singleton.class) {
                if(singleton == null) {
                    singleton = new Singleton();
                }
            }
        }

        return singleton;
    }
}

通过反射破坏单例:

Singleton singleton1 = Singleton.getSingleton();
// 通过反射获取构造函数
Constructor<Singleton> constructor = Singleton.class.getDeclaredConstructor();
// 将构造方法设置为可访问
constructor.setAccessible(true);
// 通过构造方法创建一个新的实例
Singleton singleton2 = constructor.newInstance();

System.out.print(singleton1 == singleton2); // false

解决方案:在单例类的构造方法中加判断,当实例已存在的时候,不再创建新的实例

private Singleton() {
    if(singleton != null) {
        throw new RuntimeException("单例对象只能创建一次...");
    }
}

标签:反射,Singleton,MyObject,Java,优缺点,获取,实例,Class
From: https://www.cnblogs.com/xiangningdeguang/p/16955151.html

相关文章

  • java (String)强制转换与toString()方法
    1.Object.toString()介绍Object中是自带有toString()方法的,也就是说java中的所有类的对象都是可以转换为字符串的。首先,先看看Object.toString()的默认实现public......
  • 有关JavaSe基础的反射知识总结
    反射这门技术在说之前首先来介绍一下动态语言和静态语言动态语言:在服务器运行的期间可以改变其结构的语言,在运行时代码可以根据某些条件来改变自身的结构,我们目前学习到的......
  • java方法的总结
    1.方法的作用:封装一段代码结构,可以被重复调用以提高的复用性,提高开发效率,让程序逻辑更清晰2.方法的完整的格式 修饰词返回值方法名(形参列表,形参列表){ . .. ......
  • Java中的Scanner用法解析
    (10条消息)Java中的Scanner用法解析_普通网友的博客-CSDN博客_javascannerjava-Picocli-快速构建Java命令行程序_个人文章-SegmentFault思否......
  • java最基本的判断与循环大一知识点
    1,if单选择结构 语法: if(布尔型表达式){ //如果为true(对)的表达方式 }2.if双选择结构 语法: if(布尔型表达式){ //如果为true(对)的表达方式 }else{ //为false(否)的......
  • Java 流(Stream)、文件(File)和IO
    流(Stream):一个流可以理解为一个数据的序列。输入流表示从一个源读取数据,输出流表示向一个目标写数据。 ......
  • java读取csv文件
    java读取csv文件 /***读取CSV文件内容*@paramcsvFileName*@throwsIOException*/publicstaticvoidreadCSVAndWrite(StringinputCsvFileName......
  • JavaScript文件分片上传,断点续传
    ​前言一、SpringMVC简介1.1、SpringMVC引言为了使Spring有可插入的MVC架构,SpringFrameWork在Spring基础上开发SpringMVC框架,从而在使用Spring进行WEB开发时可以......
  • java 使用hutool工具进行MD5加密
    引入依赖<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.5</version></dependency>MD5加密publicstati......
  • 05 Java 数组
    Java数组一、什么是数组数组是相同类型数据的有序集合数组描述的是相同类型的若干个数据,按照一定的顺序排列组合而成其中每一个数据称为数组元素,每个数组元素可以通过......