对Java反射的理解与应用
18年过去半个月了,说说最近身边发生的事,我妈老喜欢和我爸吵架,都六十多岁的人了,还在吵架,我爸是一个老实人,她是一个个性很强的人,而且不可理喻,但是呢,我是他们的儿子,儿不嫌母丑,我没有讨厌我妈的意思,可能是吃药的原因吧,对脑子有点影响,我总觉得我妈想不过来问题,我妈老喜欢找我把吵架,昨天给她打电话,我跟她说,您少生点气,现在全身都是病,再生气,过几天又要跑医院了,您还没抱孙子呢。跟她说,她就是听不进去,还是一个劲的说我爸,只怪我现在没能力,有能力的话,就要把他们分开,他们两分开就吵不了架了,有什么是可以商量的嘛,干嘛吵架呀,唉,我是在他们吵架中长大的,深深知道为孩子的成长很不好,为了我未来的孩子的健康成长,我尽量不要跟我未来的老婆吵架,各位网友也是记住喔,两夫妻吵架对小孩的影响很不好,少吵架,和气生财嘛。
最近在学习Retrofit,里面有很多注解,对注解不是很了解,二话不多,就在网上看注解的使用,但注解运用到了反射,又重学了一边反射,反射是Java基础,用的虽然不算多,但为了更深刻的理解,我就通过笔记记下来。
说到反射机制,先来说说Java虚拟机:
1.Java虚拟机
Java虚拟机是运行所有Java程序的抽象计算机,是Java语言的运行环境,在其上面运行Java代码编译后的字节码程序,java虚拟机实现了平台无关性。
1.1java虚拟机及其结构
java垃圾回收不需要程序员手动操作,我们经常需要关注的是java虚拟机,java虚拟机承载着程序从源码到运行的全部工作。
Java虚拟机是可运行Java代码的假想计算机,有自己想象中的硬件,如处理器、堆栈、寄存器等,还具有相应的指令系统,可以执行 Java 的字节码程序。Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。Java语言使用模式Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。
对于 JVM 的基本结构,我们可以从下图可以大致了解:
图片来自Java 虚拟机体系结构2.程序的运行过程
从源文件创建到程序运行,Java程序要经过两大步骤:编译,运行;1、源文件由编译器编译成字节码(ByteCode) 2、字节码由java虚拟机解释运行。
第一步(编译): 创建完源文件之后,程序会被编译器编译为.class文件。Java编译一个类时,如果这个类所依赖的类还没有被编译,编译器就会先编译这个被依赖的类,然后引用,否则直接引用。。编译后的字节码文件格式主要分为两部分:常量池和方法字节码。
第二步(运行):java类运行的过程大概可分为两个过程:1、类的加载 2、执行。
3.类的加载
java程序经过编译后形成*.class文件。通过类加载器将字节码(*.class)加载入JVM的内存中。JVM将类加载过程分成加载,连接,初始化三个阶段,其中连接阶段又可分为验证,准备,解析三个阶段。
4.Class对象的获取
//第一种方式 通过对象getClass方法
Person person =new Person();
Class class1 = person.getClass();
//第二种方式 通过类的class属性
class1 = Person.class;
//第三种方式 通过Class类的静态方法——forName()来实现
try {
class1 = Class.forName("com.whoislcj.reflectdemo.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
5.反射
5.1构造方法反射
Classclazz =Class.forName("photogallery.javademo.Bean");
Constructor[] conArray = clazz.getDeclaredConstructors();//获取所有的构造方法(不管是私有、受保护、默认、公有)
Constructor[] conArray1 = clazz.getConstructors();//获取public的构造方法
for(Constructor c : conArray){
System.out.println(c);
}
//反射构造方法
Constructor con = clazz.getDeclaredConstructor(String.class);
con.setAccessible(true);//暴力访问(忽略掉访问修饰符)
//反射Bean(String name)
Bean bean = (Bean)con.newInstance("wangyang");
System.out.println(bean.getName());
5.2变量反射
Classclazz =Class.forName("photogallery.javademo.Bean");
// Field[] field = clazz.getFields();
Field field = clazz.getDeclaredField("name");
field.setAccessible(true);
System.out.println(" qwqwwwqq " + clazz.getConstructors().length);
Object obj = clazz.getConstructor(String.class).newInstance("haha");
field.set(obj, "wangyang");
Bean bean = (Bean) obj;
System.out.println(" " + bean.getName());
5.3函数反射
Classclazz =Class.forName("photogallery.javademo.Bean");
Method method = clazz.getDeclaredMethod("setName", String.class);
Object obj = clazz.getConstructor().newInstance();
method.invoke(obj, "wangyang");
Bean bean = (Bean) obj;
System.out.println(" " + bean.getName());
好记性不如乱笔头,把他记下来,加深印象