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. Java并发之Synchronized机制详解

    带着问题阅读 1.Synchronized如何使用,加锁的粒度分别是什么 2.Synchronized的实现机制是什么 3.Synchronized是公平锁吗 4.Java对Synchronized做 ...

  2. 自定义-starter

    目录 说明 编写启动器 新建项目测试我们自己写的启动器 分析完毕了源码以及自动装配的过程,可以尝试自定义一个启动器来玩玩! 自动装配的过程 SpringBoot-静态资源加载-源码 SpringBoo ...

  3. Qt+Python开发百度图片下载器

    一.资源下载地址 https://www.aliyundrive.com/s/jBU2wBS8poH 本项目路径:项目->收费->百度图片下载器(可试用5分钟) 安装包直接下载地址:htt ...

  4. Java XXE漏洞典型场景分析

    本文首发于oppo安全应急响应中心: https://mp.weixin.qq.com/s?__biz=MzUyNzc4Mzk3MQ==&mid=2247485488&idx=1&am ...

  5. JSON,XML设计模式详解

    JSON在Java中的应用: Json概念: json 是一种轻量级的数据交换格式,采用完全独立于编程语言的文本格式用来存储和表示数据.JSON的语言简洁清晰,广为大众所欢迎,是一种理想的数据交换语言 ...

  6. 变着花样来接参,PHP中接收外部参数的方式

    对于PHP这样一个web语言来说,接参是非常重要的一个能力.毕竟从前端表单或异步请求传递上来的数据都要获取到才能进行正常的交互展示.当然,这也是所有能够进行web开发的语言的必备能力.今天我们就来看看 ...

  7. AD学习笔记(基础)

    AD学习 1 学习思路 1.1 学什么 1.2 怎么学 2 AD本身 3 AD project 3.1 任务层级 3.2 PCB流程 4 原理图工作环境设置 5 开始 5.1工程创建 5.2 元件库介 ...

  8. css颜色字符串转换, 字符串转化为驼峰形式

    * 将 rgb 颜色字符串转换为十六进制的形式,如 rgb(255, 255, 255) 转为 #ffffff1. rgb 中每个 , 后面的空格数量不固定2. 十六进制表达式使用六位小写字母3. 如 ...

  9. 获取用户id的方法

    /** 获取ip */function getip() { if(getenv("HTTP_X_FORWARDED_FOR")!=''){ $cip = getenv(" ...

  10. [转载]php连接postgreSQL数据库及其操作(php5,postgreSQL9)

    数据库连接:dbconn.php<?php$conn = pg_connect("host=localhost port=5432 dbname=myd user=postgres p ...