java反射

简单介绍

那么什么叫做反射呢

英语告诉我们叫:Reflection,ok,讲解完成,拜拜\n*100

ok,看来你已经看了105行了,接下来才是重点

Java的反射是指程序在运行期可以拿到一个对象的所有信息。

正常情况下,如果我们要调用一个对象的方法,或者访问一个对象的字段,通常会传入对象实例:

main

public class Main {
   public static void main(String[] args) {
       doome doome1 = new doome();
       doome1.test("获得美女微信嘻嘻嘻");
  }
}

dome

public class doome {
   public void test(String name){
       System.out.println(name);
  }
}

这样的叫做正射,也就是你知道这个类,并且去new进行调用,进行初始化,使用类去操作。当然前提是你知道这个类。

那么自然反射就知道了,你不知道这个类是什么,不能去进行初始化,我们只知道一些基本的信息。

举个栗子:
你在校园里面走路,发现一个美女,想加微信,但是不太好,求兄弟(给兄弟跪下),让他去帮你要🐎,从而获得了美女的微信
你只需要知道这个美女的特征,让兄弟(反射API)去根据你描述的信息去获得微信,你不需要知道怎么去获得的,你只要知道🐎就行
场景: 你想加一个美女的微信

过程:

你知道的特征:长发、红衣服、在图书馆(=类名+方法名+参数的字符串描述)
兄弟(反射API):接收你的特征描述,去校园里找人

兄弟的操作:
根据“长发红衣服在图书馆”找到对应的人(=Class.forName("类名"))
使用特定话术要微信(=getMethod("方法名"))
执行要微信操作(=method.invoke())

你得到的结果:微信二维码(=方法返回值)

ok,代码就出来了

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class Main {
   public static void main(String[] args) throws Exception {
       // 1. 加载类:
       Class<?> clazz = Class.forName("doome"); // 注意:类名要和上面的doome完全一致(包括大小写)//长头发

       // 2. 获取方法:
       // 参数1:方法名(你的方法是test);参数2:方法的参数类型(String.class)
       Method method = clazz.getMethod("test", String.class);//图书馆

       // 3. 获取构造器:
       Constructor constructor = clazz.getConstructor();
       //getConstructor() 找的是公有的构造器,如果要找私有的需要用 getDeclaredConstructor()//找到美女在的教室了

       // 4. 创建对象:
       Object object = constructor.newInstance();//获得对象,即兄弟找到美女了

       // 5. 调用方法
       method.invoke(object, "获得美女微信嘻嘻嘻");
  }
}

ok,那么上面的就是反射了

优缺点

缺点:

  • 破坏封装:由于反射允许访问私有字段和私有方法,所以可能会破坏封装而导致安全问题。
  • 性能开销:由于反射涉及到动态解析,因此无法执行 Java 虚拟机优化,再加上反射的写法的确要复杂得多,所以性能要比“正射”差很多,在一些性能敏感的程序中应该避免使用反射。

优点:

  • 开发通用框架:像 Spring,为了保持通用性,通过配置文件来加载不同的对象,调用不同的方法。
  • 动态代理:在面向切面编程中,需要拦截特定的方法,就会选择动态代理的方式,而动态代理的底层技术就是反射。
  • 注解:注解本身只是起到一个标记符的作用,它需要利用反射机制,根据标记符去执行特定的行为。

栗子

讲解之前让我们先了解一下

第一步

获取反射类的 Class 对象:

 // 1. 加载类:
      Class<?> clazz = Class.forName("doome"); // 注意:类名要和上面的doome完全一致(包括大小写)//长头发

首先在java里面class是一个特殊的对象,代表程序里面的类和接口。Java 中的每个类型(包括类、接口、数组以及基础类型)在 JVM 中都有一个唯一的 Class 对象与之对应。

Class 对象中包含了与类相关的很多信息,如类的名称、类的父类、类实现的接口、类的构造方法、类的方法、类的字段等等。这些信息通常被称为元数据(metadata)。

当然除了前面提到的,通过类的全名获取 Class 对象,还有以下两种方式:

  • 如果你有一个类的实例,你可以通过调用该实例的getClass()方法获取 Class 对象。例如:String str = "Hello World"; Class cls = str.getClass();
  • 如果你有一个类的字面量(即类本身),你可以直接获取 Class 对象。例如:Class cls = String.class;

第二步

通过 Class 对象获取构造方法 Constructor 对象:

 Method method = clazz.getMethod("test", String.class);//图书馆

第三步

通过 Constructor 对象初始化反射类对象:

 // 3. 获取构造器:
      Constructor constructor = clazz.getConstructor();
      //getConstructor() 找的是公有的构造器,如果要找私有的需要用 getDeclaredConstructor()//找到美女在的教室了

第四步

获取要调用的方法的 Method 对象:

// 4. 创建对象:
Object object = constructor.newInstance();//获得对象,即兄弟找到美女了

第五步

通过 invoke() 方法执行:

 // 5. 调用方法
method.invoke(object, "获得美女微信嘻嘻嘻");

机制讲解

使用反射,首先需要获得反射类的 Class 对象,每一个类,不管它最终生成了多少个对象,这些对象只会对应一个 Class 对象,这个 Class 对象是由 Java 虚拟机生成的,由它来获悉整个类的结构信息。

也就是说,java.lang.Class 是所有反射 API 的入口。

  • java.lang.Class:标识嘞的对象,提供了方法来获取类的字段、方法、构造函数等
  • java.lang.reflect.Field:表示类的字段(属性)。提供了访问和修改字段的能力
  • java.lang.reflect.Method:表示类的方法。提供了调用方法的能力
  • java.lang.reflect.Constructor:表示类的构造函数。提供了创建对象的能力

而方法的反射调用,最终是由 Method 对象的 invoke() 方法完成的

插播一下:weiny说:学新知识点的难点往往不在于语言是否清晰,而是对专业名词的理解 md,怎么感觉比如我列举出来的栗子都nb啊,服了

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇