Java反射机制
动态特性
这个问题最开始要追溯到动态语言:像Python
,PHP
这样的动态语言,在程序运行的过程中,可以改变对象的结构,属性,甚至添加方法,这是极大的灵活性。
比如,定义的person
类中,突然需要加入一个sex
属性,可以在实例中直接设置:
Python中还特有的一个eval()
函数,让语言能够进行一些奇特的实现:
char = input()
if eval("3"+char+"5"):
print("测试成功")
这就是动态语言,但是java
,c
这些是先编译为二进制静态文件,而后执行的静态语言。但是Java
不是动态语言,却能拥有动态性,其根本就在于反射。
Java产生对象的方式
new
一个实例- 通过反射构建对象
我们通过代码示例来比较这两种方法:
首先,在pojo
包下编写两个实体类Beef.class
,Chicken.class
:
package top.dongblack.pojo;
public class Beef{
public String name = "牛肉";
public int price = 25;
public String content = "今天的牛肉不怎么好吃,还贵";
public void printContent(){
System.out.println(this.content);
}
}
package top.dongblack.pojo;
public class Chicken{
public String name = "鸡肉";
public int price = 15;
public String content = "这是您的鸡肉";
public void printContent(){
System.out.println(this.content);
}
之后,我们用两种实例化方法分别进行测试:
package top.dongblack.reflect;
import top.dongblack.pojo.Beef;
public class TestNew {
public static void main(String[] args) {
Beef beef = new Beef();
beef.printContent();
}
}
package top.dongblack.reflect;
import top.dongblack.pojo.Chicken;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestReflection {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
String animal = "Beef";
String name;
Class<?> clz =Class.forName("top.dongblack.pojo."+animal);
try {
Constructor<?> cs = clz.getConstructor();
Object foodObj = cs.newInstance();
Method mt = clz.getMethod("printContent");
mt.invoke(foodObj);
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
两种方法得到的结果相同,证明这两种方法都可以实例化对象,并且调用对象的方法,得到对象的属性。那么,反射的意义究竟在哪?
动态化产生对象
我们可以看到,反射方式产生实例时,传入的是类所在的位置,换言之,是字符串,也就是说,我们可以通过字符串的拼接,生成我们想要的类。
Class<?> clz =Class.forName("top.dongblack.pojo."+animal);
这里animal
可以是beef
,可以是chicken
,当然,肉不是动物,但是无关紧要。我们可以在运行过程中得到相应的类,这就是动态化,相对于new Beef()
直接写死,这一点,反射的意义已经不言而喻了。
后话
对于反射在生产和具体场景中的应用这里没有做具体分析,以及反射的API
,大家可自行检索。