Java反射
学习就学三点:
是什么,为什么,以及怎么用.
一.是什么?
先了解几个概念:
加载流程:(你现在可以不必看懂,我会解释)
图片2————(图片出处,这是我看过的讲反射原理最好的博客)
- 编译:计算机是不认识你写的代码的(英文,汉字符号...),它只认识0和1,所以Java的编译器就会帮我们编写为字节码文件(.class文件,如图1),字节码文件只含有0 1.
- Java解释器:是JVM的一部分。Java解释器用来解释执行Java编译器编译后的程序。java.exe可以简单看成是Java解释器.
- Class类:用于表示字节码文件(.class文件)
解释:在编译时一个类会被编译为一个字节码文件,当这个字节码文件被解释执行的时候,会将.class文件从jvm的内存加载进我们的内存之中,同时创建两个class对象(这里可能就有点难懂,为什么是两个,看图2,解释的比较清楚),一个是原有class对象(为了方便,我叫他类1),一个是名字叫Class的class对象(我叫他类2),类2中存储着保存类1的全部信息如名字、父类、变量、方法...
因此,我们在程序之中只要获取类2,就可以获取类的所有属性,方法;实现我们所需的操作,方法
百度解释
JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。
看完是不是有点蒙?
其实明白反射为什么在解析执行才会错误就可以了.下面看两个例子:
①正确的例子
package com.sshqx.test;
import com.sshqx.pojo.Student;
public class Test02 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//不使用反射
Student stu1 = new Student();
System.out.println(stu1);
//使用反射
Class name = Class.forName("com.sshqx.pojo.Student");
Object newInstance = name.newInstance();
System.out.println(newInstance);
//若果想使用我这个代码,请自行生成Student的实体类
}
}
运行结果:
虽然我没给Student完成赋值,但是你可以看出它都输出了值
②错误一:
非反射获取对象错误:(假设我现在手滑,给后面要创建的实体类名打错了)
package com.sshqx.test;
import com.sshqx.pojo.Student;
public class Test02 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//不使用反射
Student stu1 = new Ssttuu();
}
}
现在显然你可以看见我的程序编译未通过,它直接就报了错误.(错误内容想看就看,不想看就过)
③错误二(关键)
package com.sshqx.test;
public class Test02 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//使用反射
Class name = Class.forName("com.sshqx.pojo.Ssttuu");
Object newInstance = name.newInstance();
System.out.println(newInstance.toString());
}
}
这里我们就能看到,它编译通过了,eclipse完全没有报任何错误(注意我的实体类依然是错的)
现在我们运行一下看看(结果可想而知)
它告诉我们类未被找到
你看出区别来了吗?
普通的我们创建对象的方式,在编译过程就已知类名,才能创建出来(否则编译过程都过不去).再看反射,编译过程完全没有问题,在解析执行时才发现问题在哪.
现在请再回去仔细一遍百度给出的反射机制的解释.然后在回来.
走你———— >百度解释
运行时加载,探知,使用(注意这些,全是动词,所以叫的动态)编译期间完全未知的classes.
动态获取信息以及动态调用对象方法的功能称为java语言的反射机制
通俗的说:java反射机制就是一个功能.什么功能?它可以帮助我们实现在运行程序过程之中,加载,探知(即"动态")一个class对象,(使用)来帮助我们实现一系列的操作(用它来创建一个对象,获取元素属性...).
二.为什么使用反射?
Java的反射机制就是增加程序的灵活性,避免将程序写死到代码里, 例如: 实例化一个 person()对象, 不使用反射, new person(); 如果想变成 实例化 其他类, 那么必须修改源代码,并重新编译。 使用反射: class.forName("person").newInstance(); 而且这个类描述可以写到配置文件中,如 **.xml, 这样如果想实例化其他类,只要修改配置文件的"类描述"就可以了,不需要重新修改代码并编译。
引用自——>https://www.zhihu.com/question/24304289
三.怎么使用
这个不多描述,网上有很多例子,随便搜搜即可.