Java:反射小记

对 Java 中的 反射,做一个微不足道的小小小小记

概念

Java 反射指的是在 Java 程序运行状态中,对于任何一个类,都可以获得这个类的所有属性和方法;对于给定的一个对象,都能够调用它的任意一个属性和方法。这种动态获取类的内容以及动态调用对象的方法称为反射机制

进一步

首先,每个类都有一个 Class 对象,包含了与类有关的信息。当编译一个新类时,会产生一个同名的 .class 文件,该文件内容保存着 Class 对象。类加载相当于 Class 对象的加载,类在第一次使用时才动态加载到 JVM 中。也可以使用 Class.forName("全限定类名") 这种方式来控制类的加载,该方法会返回一个 Class 对象。

反射可以提供运行时的类信息,并且这个类可以在运行时才加载进来,甚至在编译时期该类的 .class 不存在也可以加载进来。

实现

Class类java.lang.reflect 一起对反射提供了支持java.lang.reflect 类库主要包含了以下三个类:

  1. Field :可以使用 get()set() 方法读取和修改 Field 对象关联的字段;

    // 定义类
    class Person{
    private String name; public Person() {
    } public Person(String name) {
    this.name = name;
    } @Override
    public String toString() {
    return "Person{" +
    "name='" + name + '\'' +
    '}';
    }
    } @Test
    public void test09() throws Exception{
    Person person = new Person("李二甩");
    System.out.println(person);
    Class<? extends Person> c = person.getClass(); // 获得Person类对象 // 定义要修改的属性
    Field name = c.getDeclaredField("name");
    // 暴力反射
    name.setAccessible(true);
    // 修改属性,传入要设置的对象和值
    name.set(person, "李三甩");
    System.out.println(person); // Person{name='李三甩'}
    }
  2. Method :可以使用 invoke() 方法调用与 Method 对象关联的方法;

    class Cat{
    public void speak(String str){
    System.out.println(str);
    } public void run(int i){
    System.out.println(i + "s");
    }
    } @Test
    public void test10() throws Exception{
    Cat cat = new Cat();
    Class<? extends Cat> c = cat.getClass(); // getMethod()方法需要传入方法名,和参数类型
    Method speak = c.getMethod("speak", String.class);
    // invoke()表示调用的意思,需要传入对象和参数
    speak.invoke(cat, "喵喵"); // getMethod()方法需要传入方法名,和参数类型
    Method run = c.getMethod("run", int.class);
    run.invoke(cat,3600);
    }
  3. Constructor :可以用 Constructor 创建新的对象。

    @Test
    public void test11() throws Exception{
    Class<?> c = Class.forName("java.lang.Boolean");
    // 获取构造函数数组
    // Constructor<?>[] constructors = c.getConstructors();
    // 获取构造函数
    Constructor<?> constructor = c.getConstructor(String.class);
    Boolean bool = (Boolean) constructor.newInstance("true");
    System.out.println(bool);
    }

应用举例:工厂模式,使用反射机制,根据全限定类名获得某个类的 Class 实例。

反射的优缺点

优点:运行期类型的判断,class.forName() 动态加载类,提高代码的灵活度;

缺点:尽管反射非常强大,但也不能滥用。如果一个功能可以不用反射完成,那么最好就不用。在我们使用反射技术时,下面几条内容应该牢记于心。

  1. 性能开销 :反射涉及了动态类型的解析,所以 JVM 无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。我们应该避免在经常被执行的代码或对性能要求很高的程序中使用反射。
  2. 安全限制 :使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有安全限制的环境中运行,如 Applet,那么这就是个问题了。
  3. 内部暴露:由于反射允许代码执行一些在正常情况下不被允许的操作(比如:访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用,这可能导致代码功能失调并破坏可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。

参考

https://www.cnblogs.com/nerxious/archive/2012/12/24/2829446.html

https://mp.weixin.qq.com/s/4E3xRXOVUQzccmP0yahlqA

Java:反射小记的更多相关文章

  1. 第28章 java反射机制

    java反射机制 1.类加载机制 1.1.jvm和类 运行Java程序:java 带有main方法的类名 之后java会启动jvm,并加载字节码(字节码就是一个类在内存空间的状态) 当调用java命令 ...

  2. Java反射机制

    Java反射机制 一:什么事反射机制 简单地说,就是程序运行时能够通过反射的到类的所有信息,只需要获得类名,方法名,属性名. 二:为什么要用反射:     静态编译:在编译时确定类型,绑定对象,即通过 ...

  3. java反射(基础了解)

    package cn.itcast_01; /** *Person类 */ public class Person {    /** 姓名 */    private String name;     ...

  4. java基础知识(十一)java反射机制(上)

    java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时 ...

  5. java基础知识(十一)java反射机制(下)

    1.什么是反射机制? java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用他的属性和方法,这种动态获取属性和方法的功能称为java的反射机制. ...

  6. java反射学习之二万能EXCEL导出

    一.EXCEL导出的实现过程 假设有一个对象的集合,现在需要将此集合内的所有对象导出到EXCEL中,对象有N个属性:那么我们实现的方式是这样的: 循环这个集合,在循环集合中某个对象的所有属性,将这个对 ...

  7. java反射学习之一反射机制概述

    一.反射机制背景概述 1.反射(reflection)是java被视为动态语言的一个关键性质 2.反射机制指的是程序在运行时能获取任何类的内部所有信息 二.反射机制实现功能概述 1.只要给定类的全名, ...

  8. java反射 之 反射基础

    一.反射 反射:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为 ...

  9. java反射 cglib asm相关资料

    有篇文章对java反射的调用的效率做了测试,写的比较好.猛击下面地址 http://www.blogjava.net/stone2083/archive/2010/09/15/332065.html ...

随机推荐

  1. noip模拟33

    \(\color{white}{\mathbb{失足而坠千里,翻覆而没百足,名之以:深渊}}\) 这场考试的时间分配非常不科学 开题试图想 \(t1\) 正解,一个半小时后还是只有暴力,特别惊慌失措 ...

  2. three+pixi 将二维和三维结合

    PIXI+THREE 使用 PIXI 和 THREE 将三维和二维渲染在同一个 canvas 下面 效果 思路 初始化 PIXI 的 Application, 作为 pixi 最重要的变量 const ...

  3. 解决CSDN文章下载后,依然请求跳转至首页出错的问题

    1. 搜索关键字:"onerror"     然后找到如下所示代码: <div style="display:none;">     <img ...

  4. Dubbo No provider问题排查思路

    本文已收录 https://github.com/lkxiaolou/lkxiaolou 欢迎star. 不想看字的同学可直接划到底部查看思维导图 问题分析 使用过Dubbo的朋友很多都碰到过如下报错 ...

  5. .NET 6 RC1 正式发布

    昨天晚上微软发布了.NET 6的两个RC版本中的第一个版本,该版本将于11月正式发布,作为在开源MIT协议下整合所有不同的.NET开发模组件的开源跨平台实现.这是一个从2014年开始,持续多年的,以改 ...

  6. 回忆之placeholder

    直接看效果点这里 HTML <!DOCTYPE html> <html> <head lang="zh-CN"> <meta charse ...

  7. TP5指定讲师页面文章上下篇

    控制器代码 // 查询上下篇 $courseIds = model('course') ->where([ 'isdel' => 0, 'teacherid' => $teacher ...

  8. Linux系列(5) - 目录处理命令(2)

    删除空目录: rmdir rmdir [目录名] 删除文件或目录: rm rm  -rf  [文件或目录] 选项 -r            删除目录 -f                   强制 ...

  9. jenkin—持续集成

    jenkins与持续集成 Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能.(百度百科) 持续集 ...

  10. P3964-[TJOI2013]松鼠聚会【计算几何】

    正题 题目链接:https://www.luogu.com.cn/problem/P3964 题目大意 给出\(n\)个点,求一个点使得它到所有点的切比雪夫距离和最小. \(0\leq n\leq 1 ...