java的反射机制和工厂模式
程序员文章站
2022-03-09 20:30:20
...
在程序中使用new去生成一个对象,然后执行这个文件的过程叫做静态编译。这种方式不利于大型项目的迭代。
使用反射机制便捷的利用工厂模式可以快速的动态编译。
-
那么什么是反射机制?
-
先了解JAVA的执行逻辑:
1.Srouce 编写java源代码 生成.class字节码文件 2.加载 类加载器在该类被使用的时候,把字节码文件加载到JVM去执行 3.生成对象 new Object() 在.class文件中包含有java类中全部的基本信息【类名,方法,属性】 那么我们完全可以在这个文件中得到我们要生成的类名和要使用的方法。
所以回答上面的问题:什么是反射机制? 通过类名可以获得和操作他的全部信息的这种方式叫做反射机制
那么如何获得该类的class?
- Class类提供方法:class file = Class.forName(“全类名”);
- 类名.class class file = Person.class
- Object提供方法:class file = Person.getclass()
得到class之后,Class类提供一些系列方法,允许程序员去访问该类的各类信息
- Field getField(“指定的属性名”)
- Fields[ ] getFields() //全部的Public属性名
- Field getDeclareField(“指定的属性名”)
- Field[ ] getDeclareFields()//全部的属性名【忽略访问权限】
- setAccessible(true);//3,4配合这个方法一起使用
Method getMethod()
Construct getConstructor//基本类似与field
详细参考javaAPI文档Class类
获得构造器以后就可以利用 newInstance 去创建对象【据说被弃用,有新 的方法】
- 先写一个Person类
package Exam
class Person{
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void eat() {
System.out.println("eat...");
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
- 写配置
/*
获得Person的class文件,对
*/
class cls = Class.forName("Exam.Person");
//此处该写全类名 包名+类名
Object p = cls.newInstance();
// Field file = cls.getField("name") //此处报错,因为是私有属性
Field fielditem = cls.getDeclaredField("name");
//忽略访问权限修饰符 true则忽略 【暴力反射】
System.out.println(fielditem);
//设置该属性的可访问权限,true为可以访问
fielditem.setAccessible(true);
fielditem.set(p,"张三");
System.out.println(p.toString());
//基本等于 Person p = new Person();
// p.name="张三"
以上就是反射机制了。【也就是程序员说的高大上,其实就是利用class去操作这个类的成员,而不是直接去new,然后obj.成员】
不理解的话,想想泛型!
知道了反射机制,那么工厂模式呼之而出:
全类名不由factor类【就是我们上面的那么配置代码】直接给出。而是由一个单独的配置文件给出。我们只需要从该配置文件中读取数据就可以。然后基本操作一致。
那么如何找到这个配置文件,并且读取数据呢?
- 已知类加载器是可以找到各类信息的,同样的它也可以找到给定名字的资源文件
- 利用Properties去读取信息,持久化保持
InputStream is = ReflectFrame.class.getClassLoader()
.getResourceAsStream("pro.properties");
//本来是应该相连在一起的,但是会忽略空行,这样看起来结构清晰
//ReflectFrame是我定义的另一个工厂类
/*这段代码的意思是该工厂类的类加载器去找一个名为pro.properties的资源文件,
以输入字节流的形式返回。因为后面要用到的Properities是需要这么个输入流的
*/
Properties Pro = new Properties();
Pro.load(is);
/*
Properies对象所提供的的最大用途在于
Properties可以保存到流中或从流中加载。
属性列表中的每个键及其对应的值都是一个字符串。
load(is) 从is输入字节流读取属性列表(键和元素对)。
这样我们就有了全部配置信息的键值对信息
*/
得到类信息的键值对以后,就把value取出,这个value就是我们要创建的这个类的全部信息了
String ClassName = Pro.getProperty("ClassName");
//getProperty("key")使用此属性列表中指定的键搜索属性。
String MethodName = Pro.getProperty("MethodName");
//得到该class
Class cls = Class.forName(ClassName);
//创建对象
Object obj =cls.newInstance();
//获取该对象的方法
Method method =cls.getMethod(MethodName);
method.invoke(obj);
以上就是基本的工厂模式
总结:工厂模式就是配置文件+反射机制
上一篇: 工厂设计模式中的反射问题