惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
C
Cybersecurity and Infrastructure Security Agency CISA
IT之家
IT之家
罗磊的独立博客
阮一峰的网络日志
阮一峰的网络日志
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
L
LINUX DO - 最新话题
C
Cyber Attacks, Cyber Crime and Cyber Security
Cyberwarzone
Cyberwarzone
S
SegmentFault 最新的问题
S
Schneier on Security
A
About on SuperTechFans
L
Lohrmann on Cybersecurity
博客园_首页
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Securelist
博客园 - 司徒正美
H
Hacker News: Front Page
Jina AI
Jina AI
K
Kaspersky official blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
量子位
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
J
Java Code Geeks
B
Blog
Google DeepMind News
Google DeepMind News
博客园 - Franky
The Cloudflare Blog
M
MIT News - Artificial intelligence
Blog — PlanetScale
Blog — PlanetScale
H
Help Net Security
Spread Privacy
Spread Privacy
N
News and Events Feed by Topic
A
Arctic Wolf
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
宝玉的分享
宝玉的分享
T
The Blog of Author Tim Ferriss
O
OpenAI News
N
Netflix TechBlog - Medium
G
GRAHAM CLULEY
F
Fortinet All Blogs
V
V2EX
N
News | PayPal Newsroom
Y
Y Combinator Blog
雷峰网
雷峰网
博客园 - 叶小钗
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Recent Commits to openclaw:main
Recent Commits to openclaw:main

技术改变视野

为程序员、设计师打造的摸鱼社区:摸鱼派! - 技术改变视野 大白话 | Java初学指♂男:“说说初学的误区与死结”( 壹 | 反射与Field ) - 技术改变视野 大白话之耦合性:什么是耦合性和内聚性?用编程语言实例讲解! - 技术改变视野 🎨 适用于 Solo / Bolo 的清新高级主题 —— Sakura | 移植自 WordPress 主题 - 技术改变视野 我在 GitHub 上的开源项目 - 技术改变视野 为IDEA/Git配置GPG密钥,点亮GitHub Verified Commit标识 - 技术改变视野 从 SpringMVC 转为使用 SpringBoot —— 手把手带你使用 Intellij IDEA 最快速地搭建 SpringBoot+MyBatis(无 XML)+Thymeleaf - 技术改变视野 无题 - 技术改变视野 年轻人的第一辆京牌电动车 - 技术改变视野 我们忙碌且漫长的一生,有多久是为自己而活? - 技术改变视野 一个最简单的实例理解Semaphore在Java中的作用 - 技术改变视野 说说《后浪》 - 技术改变视野 离线使用 Google Fonts:让你的网站更精致 | goofoffline 神器,一键下载生成离线字体库! - 技术改变视野 实例带你学会简单的Java Thread多线程 - 技术改变视野 一个实例理解Java的接口(interface)用处与用法 - 技术改变视野 一个实例带你理解JavaBean - 技术改变视野 WebFilter-SpringBoot过滤器注解实例讲解 - 技术改变视野 实例带你搞懂Java多线程&&线程池之(壹):线程池与多线程的关系和区别 - 技术改变视野 实例带你搞懂Java多线程&&线程池之(贰):简单的线程池应用 - 技术改变视野 实例带你获取多线程Thread的返回值之 (壹) - Callable的运行 - 技术改变视野 实例带你获取多线程Thread的返回值之 (贰) - Callable配合线程池返回数据 - 技术改变视野 一个实例理解Java Runnable多线程用处与用法 - 技术改变视野 从零开始OpenSSL之 (壹) - 使用genrsa、rsa、rsautl生成公私钥 - 技术改变视野 从零开始 OpenSSL 之 (贰) - 使用 rsautl 解密文件 - 技术改变视野 大白话之Docker(壹):快速入门&&简单官方实例 - 技术改变视野 大白话之Docker(贰):简单部署一个Tomcat服务并发布内容 - 技术改变视野 大白话之从零讲解DVWA(壹)-SQL注入(SQL Injection) Low Level - 技术改变视野 大白话之从零讲解DVWA(贰)-SQL注入(SQL Injection) Medium/High Level - 技术改变视野 Java日志插件-Slog4J下载 - 技术改变视野 大白话之必会Java Atomic | 线程一点也不安全(一):比自增和synchronized更快速、靠谱的原子操作(调用C语言) - 技术改变视野 Log-MySQL root用户登录后无法查看数据库全部表/正常访问数据库 Access denied for user 'root'@'localhost' to database - 技术改变视野 大白话之Docker(叁):制作一个运行Tomcat服务端的Docker镜像 - 技术改变视野 Github仅保留指定文件/文件夹当前Commit,删除所有历史记录,清除「敏感信息」 - 技术改变视野 将Tomcat、MySQL从Linux迁移到Windows的心路历程(干货):令人恐惧的字符编码 - 技术改变视野 Spring: java.lang.NoSuchMethodError: clearCache | ClassNotFoundException | Error during artifact deployment 思路及解决办法 - 技术改变视野 大白话之Java面向接口编程:最“正经”的中文实例讲解,看不懂来打我! - 技术改变视野 大白话 | 课堂实践:使用Iterator对数组进行遍历 - 技术改变视野 大白话之fail-fast | fail-safe:为什么会有这个机制?它有什么作用? - 技术改变视野 刨根问底 | 大白话:在使用注解后,框架是怎么知道你哪个方法使用了注解的?用@RequestMapping注解举例详解! - 技术改变视野 大白话之必会Java Atomic | 线程一点也不安全(二):Atomic的ABA问题会导致什么情况?如何解决? - 技术改变视野 随笔 | 奇淫技巧 | Java:记return和短路运算符的妙用 - 技术改变视野 随笔 | Tomcat:续-从Linux迁移到Windows编码问题彻底解决 - 技术改变视野 大白话之AutoClosable接口 | try-with-resources:JDK1.7的新特性,提高重复回收效率 - 技术改变视野 大白话之Java多线程join方法:开局一张图,试学一分钟,你就费和我一样,理解介个方法 - 技术改变视野 大白话之Java Stream流:将类数组流化,便捷批量修改,通俗讲解! - 技术改变视野 Java 困扰三周の问题:使用byte[]或skip()方法读取字节流Stream文件尾部多/少/缺字节解决方法 - 技术改变视野 大白话之Java级联调用:一个类,一条语句,同时调用好几个方法,串成一串 - 技术改变视野
大白话之Java反射-初学最迷的概念:能干啥?咋用? - 技术改变视野
adlered · 2019-12-09 · via 技术改变视野

前言

初学时,反射、网络编程、IO是我最不能理解的三大模块。
当时查资料,给我的感觉是:写文章的都觉得我已经会了。
如今,我用实例尽可能简单地讲述反射这个东西。

能干啥?

人类文明分为三个阶段:

  1. 女娲创造人类
  2. 人类文明建立,地球产生秩序
  3. 人类灭亡

实例化

平常我们实例化一个类,都是用:

1Main main = new Main();

那如果要读取这个类中的公共变量,我们需要:

 1public class Main {
 2    public String value = "HelloWorld!";
 3}
 4
 5public class Test {
 6    public static void main(String[] args) {
 7        Main main = new Main();
 8        System.out.println(main.value);
 9    }
10}

那么我们如果将这个变量设置为私有呢?

1public class Main {
2    private String value = "HelloWorld!";
3}

很明显,我们无法获得该变量的值,因为变量的作用域止步于自己的类中。

那么如果我们使用反射,我们就能获取到这个类的任何信息,无论它是私有的还是什么乱七八糟的,不但能看,还能改。

本章主要讲述方法的调用。修改值的方法八九不离十,在阅读本篇文章后,阅读其它文章将会很好理解。

所以...

回到那个人类文明的话题。

如果女娲完成了自己的任务,并且人类已经进入了文明时代后。
我们想操控所有人的思想和命运,怎么办?

对,上帝模式。

如果我们是上帝,我们就能掌握自己管辖区域内的任何物质,包括人类和大自然。

那么...

Java的反射就犹如上帝模式一样。我们一般使用Java反射可以用来:

 1加载类;
 2得到类的包名、父类和实现的接口;
 3得到类默认方法的参数;
 4得到类中的变量参数;
 5修改类中的变量参数;
 6得到类的方法名,方法的参数,方法的返回类型;
 7调用类中的方法;
 8得到类中的注解信息;
 9得到类中的泛型信息;
10修改类中的数组;
11等等等等......

类的运行过程中,有些参数可能是不可控的。通过反射,我们可以深入掌握自己编写的类,同时在以后的项目和调试中也会有所应用。

咋用?

假设我们再写一个需求(伪代码):

1Class Values {
2	String value1 = "Hello";
3	String value2 = "World";
4}
5
6Class Main {
7	String str = "value2";
8}

假设变量str的内容是不可控的,但str的值一定是Values类中的一个变量,我们想将制定str值的变量修改... 应该怎么做呢?

首先,修改Values类中的方法:

 1public class Values {
 2    public static String value1 = "Hello";
 3    public static String value2 = "World";
 4
 5    public String getValue1() {
 6        return value1;
 7    }
 8
 9    public void setValue1(String value1) {
10        this.value1 = value1;
11    }
12
13    public String getValue2() {
14        return value2;
15    }
16
17    public void setValue2(String value2) {
18        this.value2 = value2;
19    }
20}
21

此时,如果我们想修改Value2的值,只需执行Values类中的方法setValue2(String value2)即可。例:

1setValue2("NaN");

此时,Value2的值为“NaN”。

Brain Storm

如果你仔细阅读了上方的内容,你会发现反射支持一个特性:

1调用类中的方法。

那么,如果我们利用反射调用这个方法,就可行了。

编写Main.java中的代码:

 1import java.lang.reflect.Method;
 2
 3public class Main {
 4    //将要调用的方法
 5    private static String str = "setValue2";
 6
 7    public static void main(String[] args) {
 8        try {
 9            //执行Class.forName("类")时,JVM会查找对应的类并加载,这时JVM会执行该类的静态代码段。
10            Class clazz = Class.forName("Values");
11            /*
12            不使用 > Values values = new Values(); <
13            是因为 > Class.forName() < 是获取正在运行的实例,而 > new() < 会创建一个新的实例。
14            Values中的变量是静态的,所以它的值在启动时已经写入了内存,我们必须直接修改内存中的值,而不是再新建一个。
15             */
16            Values values = (Values) clazz.newInstance();
17            /*
18            getMethod(方法名, 传值1类型, 传值2类型, ...)
19            获取指定的方法对象
20            传值类型:String.class Integer.class 等等
21             */
22            Method method = clazz.getMethod(str, String.class);
23            System.out.println("修改前:" + Values.value2);
24            //调用指定方法的 > 方法对象.invoke(值实例, 传值1, 传值2, ...) <
25            method.invoke(values, "NaN");
26            System.out.println("修改后:" + Values.value2);
27        } catch (Exception E) {
28            E.printStackTrace();
29        }
30    }
31}
32

得到返回结果:

1修改前:World
2修改后:NaN

后语

这样,我们就相当于将字符动态转换为了一段可运行的代码,就能实现更多的功能了。

调用方法,修改值只是反射的一小部分作用。在将来的学习中你会学习到更多的使用姿势,帮助你完成更复杂的设计需求!