云时代的 JVM 原理与实战
康杨
京东资深架构师
3111 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 39 讲
云时代的 JVM 原理与实战
15
15
1.0x
00:00/00:00
登录|注册

08|反射机制:给你一把打开JVM后门的钥匙

你好,我是康杨,今天我们来聊聊 JVM 中的反射机制。
在有反射之前,JVM 对我们来说就像是一个黑盒。我们与它的交互,仅仅是在编译期之前,我们遵照 Java 语法写了一段程序,之后 JVM 如何编译,运行期如何执行我们不得而知,也和我们无关。这就像我们进入一家饭店 ,服务员递给我们一份菜单,我们能做的就是照着菜单去点菜,对于普通的消费者,一份精美菜单已经足够了。
就像下面这段代码 ,我们不需要做任何事情,构造器不用传入任何参数,就能得到一份蘸酱小黄瓜。
// 蘸酱小黄瓜
public class DippedSauceCucumbers {
private String mainIngredient = "黄瓜";
private String dippingSauce = "豆瓣酱";
private String menu ="";
public DippedSauceCucumbers() {
setMenu();
}
// 设置菜单
private void setMenu() {
menu = "蘸酱小黄瓜{" +
"mainIngredient='" + mainIngredient + '\'' +
", dippingSauce='" + dippingSauce + '\'' +
'}';
}
// 打印菜单
public void printMenu(){
System.out.printf(menu);
}
public static void main(String[] args) throws Exception {
DippedSauceCucumbers dippedSauceCucumbers = new DippedSauceCucumbers();
dippedSauceCucumbers.printMenu();
}
}
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了Java虚拟机(JVM)中的反射机制,通过反射API可以在运行时动态加载类、获取类的内部信息、动态创建对象并调用其属性。文章通过实例展示了如何利用反射机制来定制菜单,以及获取Class对象的三种方式。反射机制的实现依赖于类加载机制,通过Class对象可以获取Method、Field类对象,实现对类的操作和定制。文章还详细介绍了Java.lang.Class的获取方式和使用方法。总的来说,反射机制赋予了Java动态性和运行时自我认知的能力,使得程序可以在运行时观察甚至修改JVM的行为。反射机制的应用场景也得到了详细的阐述,包括在运行时动态扩展JVM的提供能力和基于JVM提供的能力打造一个定制的图灵机。文章还提出了反射机制的重要性,并留下了两个思考题,引发读者深入思考。整体而言,本文内容丰富,深入浅出,对于想要深入了解Java反射机制的读者具有很高的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《云时代的 JVM 原理与实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(5)

  • 最新
  • 精选
  • Demon.Lee
    获取 Class 对象的三种方式,其动态性不断降低,没太理解。既然拿到了 Class 对象这把钥匙,不管哪种方式拿到,其本质不都一样吗,后面想怎么玩就怎么玩。我是不是角度理解错了。

    作者回复: 当我们说获取 Class 对象的三种方式动态性不断降低,主要是指在编译期和运行期对类的依赖度和耦合程度:Class.forName方式是最具动态性的,因为这种方式既可以在编译期确定,也可以在运行期通过动态拼接类名字来获取,具有很高的灵活性。但是因为其是运行时动态加载,所以如果类在编译期不存在,运行期加载的时候就会出现ClassNotFoundException。对象的.getClass方式其次,这种方式需要有实例对象,所以使用这种方式一般是已经明确了具体的类,还能保证该类一定存在。所有的方式拿到的Class对象本质上都一样,都可以用来获取类的信息或者进行反射操作等。主要考虑的是在使用的时候有着不同的便捷程度,以及各自适应不同的应用场景,所以就有了动态性的划分。

    2023-09-07归属地:安徽
    3
  • 白不吃
    深度差点意思
    2023-09-27归属地:湖北
    3
  • ^_^
    1,获取一个 class 对象不同方式的差异点 1), 对象的getClass()方法获取的Class对象是针对具体的对象的,而.class语法和Class.forName()方法获取的Class对象是针对类本身的。 2),使用对象的getClass()方法获取的Class对象是在运行时动态获取的,而使用.class语法和Class.forName()方法获取的Class对象是在编译时就确定的。 3),使用.class语法和Class.forName()方法获取的Class对象可以在没有实例化对象的情况下使用,而对象的getClass()方法需要有一个实例化对象才能调用。 2,如何通过反射机制获取某个类以及它继承的类的所有公有字段 public class MyClass { public int publicField; private int privateField; protected int protectedField; public static void main(String[] args) { try { // 获取类的Class对象 Class<?> clazz = MyClass.class; // 获取类的所有公有字段 Field[] fields = clazz.getFields(); // 遍历字段数组并处理字段 for (Field field : fields) { // 输出字段的名称和类型 System.out.println("Field name: " + field.getName()); System.out.println("Field type: " + field.getType()); } } catch (Exception e) { e.printStackTrace(); } } }
    2023-09-06归属地:北京
    2
  • C.
    第一个问题:Class.forName静态方法一般用于加载驱动或者判断类是否存在的情况,.class必须事先知道有这个类,object.getClass必须要有类实例对象。 第二个问题:clazz.getFields();//获取当前类及其父类的所有公有字段。clazz.getDeclaredFields();//取私有字段或受保护的字段和公共字段。
    2023-09-08归属地:江苏
  • peter
    Q1:最简单程序,只是打印一个“hello”字符串;此程序的运行,会有哪些类加载器参与? 以及加载顺序? Q2:JAVA的“动态性”,除了反射,还有其他的吗?
    2023-09-06归属地:河南
收起评论
显示
设置
留言
5
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部