首页 / 知识
Java反射机制原来没有那么难
2023-04-11 13:09:00

前言
反射是被视为动态语言的关键,反射机制允许程序在执行期间借助于Reflection API取得任何类得内部信息,并能够直接操作任意对象得内部属性和方法(包括私有)。
加载完类之后,在方法区中就会产生一个Class类型对象,这个对象就包含了完整得类得结构信息。我们可以通过这个对象看到类得结构。这个对象就像就像一面镜子,透过这个镜子可以看到类得结构,所以,我们形象得称之为:反射。
所以我们首先简单的讲一下类加载,然后在讲反射机制。
类加载
类加载步骤
分为三步:加载、链接、初始化
加载Loading
作用:在内存中生成一个代表这个类的Class对象,作为方法区中这和类的各种数据的访问入口。
什么时候加载?
- new
- Class.forName(“包名。类名”)
怎么加载?
Bootstrap(根加载器,加载$JAVA_HOME/jre/lib/rt.jar包内的class文件,包含java运行环境所需的基础类)
ExtClass(加载$JAVA_HOME/jre/lib/ext/.jar目录下的class文件)
AppClass(用于——加载当前应用的classpath的所有类)
链接 Linking
该过程分三个阶段:验证、准备、解析
验证:验证阶段用于确保加载的Class文件的字节流包含的信息是否符合虚拟机要求,保证其合法性。
准备阶段: 为类变量(静态变量)分配内存并跟根据对象类型赋对应的默认值。
解析阶段:用于将符号引用转换为直接引用。
初始化 initialization
执行类的构造方法的过程
反射技术
运行时动态访问对象的属性和方法。
Class对象
上面我们简单的了解了以下类加载机制。
那我们如何得到Class对象呢?
通常我们又三种方法:
第一种,使用 Class.forName 静态方法。 前提:已明确类的全路径名。
第二种,使用 .class 方法。 说明:仅适合在编译前就已经明确要操作的 Class
第三种,使用类对象的 getClass() 方法。 适合有对象示例的情况下
代码:
package com.dyit.clazz;
public class GetClass {
//定义一个内部类
static class A {
public A() {
}
public void print() {
System.out.println("内部类");
}
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
//得到class对象
System.out.println(A.class);
A b = new A();
System.out.println(b.getClass());
System.out.println(Class.forName("com.dyit.clazz.GetClass$A"));
}
}
结果截图:
那我们拿到Class对象可以干什么呢?
之前我们类的实例化有三种方式:
new 关键字
克隆
反序列化
现在我们可以通过类的Class对象创建类的实例
通过Class.newInstance()可以得到类的实例;
可以通过Class.getSimpleName()得到类的名称
代码如下:
package com.dyit.clazz;
public class ClassDemo {
//定义一个内部类
static class A {
public A() {
}
public void print() {
System.out.println("内部类");
}
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
//得到Class对象
Class<A> a = A.class;
//得到类的名称
System.out.println(a.getName());
System.out.println(a.getSimpleName());
//创建实例
A b = a.newInstance();
//调用方法
b.print();
}
}
结果:
Field类
描述类中的属性,(数值)域
首先通过Class对象得到所有的属性
Class.getDeclaredFields()
通过设置field.setAccessible(true)可以访问私有属性。
field.get(c) 得到c关于这和属性的值
field.getName()得到属性的名称
field.getType()得到属性的类型
field.getType()。getSimpleName()得到属性的简单名称
可以通过set方法设置对象属性的值:field.set(c, 999.99)
|
最新内容
相关内容
python详解Python垃圾回收机制
python详解Python垃圾回收机制,技术,时间,培训,对象,系统,名字,垃圾,标记,机制,内存,引用计数python默认的垃圾收集机制是“引用计数”,每个对pythonTKinter的消息传递机制
pythonTKinter的消息传递机制,培训,系统,消息,机制,事件,函数,程序,队列,组件,框架,pythonTKinter的消息传递机制1、自动发送事件/消息。2、没有Emacs的Lisp / Scheme解释器?
没有Emacs的Lisp / Scheme解释器?,没有Emacs的Lisp / Scheme解释器?,命令行,解释器,解释程序,我一直,Lisp/Scheme interpreter without关于javascript:添加多个window.onl
关于javascript:添加多个window.onload事件,关于javascript:添加多个window.onload事件,事件,用户控件,我向,添加,Add multiple window关于函数式编程:在 JavaScript 中使
关于函数式编程:在 JavaScript 中使用 Array.map 删除元素,关于函数式编程:在 JavaScript 中使用 Array.map 删除元素,过滤,函数,项目关于java:我可以在TestNG测试用例上
关于java:我可以在TestNG测试用例上指定类范围的组吗?,关于java:我可以在TestNG测试用例上指定类范围的组吗?,扩展,数据库,基类,我想,Can关于体系结构:我应该如何构建Java应
关于体系结构:我应该如何构建Java应用程序,将类放在哪里?,关于体系结构:我应该如何构建Java应用程序,将类放在哪里?,应用程序,支持,困惑,我可以使用JavaScript创建客户端电
我可以使用JavaScript创建客户端电子邮件吗?,我可以使用JavaScript创建客户端电子邮件吗?,客户端,邮件,网页,操作,Can I use JavaScrip我应该如何将文件加载到Java应用程
我应该如何将文件加载到Java应用程序中?,我应该如何将文件加载到Java应用程序中?,文件,应用程序,加载,文本,How should I load files i关于linux:Java时区混乱
关于linux:Java时区混乱,关于linux:Java时区混乱,默认,显示,发现,应用程序,Java Time Zone is messed up我正在运行Tomcat应用程序,并且关于javascript:从下拉框中获取文本
关于javascript:从下拉框中获取文本,关于javascript:从下拉框中获取文本,选择,下拉,这将,菜单中,Getting the text from a drop-down b关于sql server:没有主键的表
关于sql server:没有主键的表,关于sql server:没有主键的表,数据,客户端,几个,我有,Tables with no Primary Key我有几个表,其唯一的数