反射(得到Class类的几种方式)
目录:
1)java反射机制概述
2)理解Class类并获取Class实例
3)类的加载与ClassLoader
4)创建运行时类的对象
5)获取运行时类的完整结构
6)调用运行时类的指定结构
一---基本概念
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法(即使是private的),可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键(来自 百度百科)。
一句话概述就是利用反射,底裤都能扒出来。
游戏外挂的原理:游戏在运行的时候,通过反射去改变运行时的参数,从而达到作弊的目的。
正常方式:引入需要的包类名称->通过new实例化->取得实例化对象
反射方式:实例化对象->getClass()方法->得到完整的包类名称
加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象,通过这个对象我们可以看到类的结构。
1 package reflection; 2 3 4 public class test01 extends Object{ 5 public static void main(String[] args) throws ClassNotFoundException{ 6 // 通过反射获取类的class对象 7 Class c1 = Class.forName("reflection.user"); 8 System.out.println(c1); 9 Class c2 = Class.forName("reflection.user"); 10 Class c3 = Class.forName("reflection.user"); 11 Class c4 = Class.forName("reflection.user"); 12 13 // 一个类在内存中只有一个class对象 14 // 一个类被加载后,类的整个结构都会被封装在class对象中 15 System.out.println(c2.hashCode()); 16 System.out.println(c3.hashCode()); 17 System.out.println(c4.hashCode()); 18 19 } 20 } 21 22 // 实体类 23 class user { 24 private String name; 25 private int id; 26 private int age; 27 28 public user() { 29 } 30 31 public user(String name, int id, int age) { 32 this.name = name; 33 this.id = id; 34 this.age = age; 35 } 36 37 public String getName() { 38 return name; 39 } 40 41 public void setName(String name) { 42 this.name = name; 43 } 44 45 public int getId() { 46 return id; 47 } 48 49 public void setId(int id) { 50 this.id = id; 51 } 52 53 public int getAge() { 54 return age; 55 } 56 57 public void setAge(int age) { 58 this.age = age; 59 } 60 61 @Override 62 public String toString() { 63 return "user{" + 64 "name='" + name + '\'' + 65 ", id=" + id + 66 ", age=" + age + 67 '}'; 68 } 69 }
运行结果:无论创建多少个对象,Class的类型都只有一个
反射的优缺点
1)优点:可以动态创建对象和编译,灵活性大
2)缺点:对性能有影响,我们告诉虚拟机我们要做什么,让他去干,命令下达和他完成完有一个时间延迟。直接new出来的和反射出来的差了好几十倍。
反射主要的API:
1)java.lang.Class:代表一个类 (记住这个)
2)java.lang.reflect.Method: 代表类的方法
3)java.lang.reflect.Field:代表类的成员变量
4)java.lang.reflect.Constructor:代表类的构造器
Class类:
在Object类中定义了以下的方法,此方法将被所有子类继承
1 public final native Class getClass();
1)Class本身也是一个类
2)Class对象只能由系统建立对象
3)一个加载的类在JVM中只会有一个Class实例
4)一个Class对象对应的是一个加载到JVM中的一个class文件
5)每个类的实例都会记得自己是由哪个Class实例所生成
6)通过Class可以完整的得到一个类中的所有被加载的结构
7)Class是reflection的根源,针对任何你想动态加载,运行的类,唯有先获得相应的Class对象
Class类的常用方法:
获取Class类的实例:
1)若已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高
Class clazz = Person.class
2)已知某个类的实例,调用该实例的getClass()方法获取Class()对象
Class clazz = person.getClass()
3)已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,
可能抛出ClassNotFoundException
class clazz = Class.forName("demo01.Studengt")
4)内置基本数据类型可以 直接用类名.Type
测试代码:
1 package reflection; 2 3 public class test02 { 4 public static void main(String[] args) throws ClassNotFoundException { 5 Person person = new Student(); 6 System.out.println("这个人是" + person.name); 7 // 方式一: 通过对象获得 8 Class c1 = person.getClass(); 9 System.out.println(c1.hashCode()); 10 11 12 // 方式二: forName获得 13 Class c2 = Class.forName("reflection.Student"); 14 System.out.println(c2.hashCode()); 15 16 // 方式三: 通过类名.class获得 17 Class c3 = Student.class; 18 System.out.println(c3.hashCode()); 19 20 // 方式四: 基本内置类型的包装类都有一个Type属性 21 Class c4 = Float.TYPE; 22 System.out.println(c4); 23 24 // 获得父类的类型(这里就是通过对象获取类) 25 Class c5 = c1.getSuperclass(); 26 System.out.println(c5); 27 28 } 29 } 30 31 class Person { 32 String name; 33 int age; 34 35 public Person() { 36 } 37 38 public Person(String name, int age) { 39 this.name = name; 40 this.age = age; 41 } 42 43 } 44 45 class Student extends Person { 46 public Student() { 47 this.name = "学生"; 48 } 49 } 50 51 class Teacher extends Person { 52 public Teacher() { 53 this.name = "老师"; 54 } 55 }
结果:
posted on 2021-04-11 10:30 Love&Share 阅读(771) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~