1. 工厂模式
- 开发中有一个非常重要的原则“开闭原则”,对拓展开放、对修改关闭;
- 工厂模式主要负责对象创建的问题;
- 可通过反射进行工厂模式的设计,完成动态的对象创建。
public class TestNewInstanceForFile {
public static void main(String[] args) throws Exception {
// 创建出入流对象
FileReader fr = new FileReader("files\\application.txt");
BufferedReader br = new BufferedReader(fr);
// 读出文件中的类的全限定名
String className = br.readLine();
// 创建Object对象返回后进行强转为对应类型,进而使用
Teacher t3 = (Teacher)createObject(className);
System.out.println(t3);
br.close();
}
/**
* 工厂:创建对象工厂
* @param className String类型的类的全限定名
* @return Object Object类型的对象
*/
public static Object createObject(String className) {
try {
Class<?> c = Class.forName(className);
return c.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
/*
* files\\application.txt 内容:
* com.methods.Teacher
*/
2. 通用编程
使用反射机制,实现执行任何类的任意方法。
突破封装示例:
// 反射:类的对象
Object o = createObject("com.day.t1_factory.Student");
// 类对象
Class<?> c = o.getClass();
Method m = c.getDeclaredMethod("calc", null); // 获取自身方法,包含私有方法
// 【注意】反射是一种底层技术,可取消语言检查,突破private封装!
// AccessibleObject类:@true 忽略Java语言访问检查 @false 反之
m.setAccessible(true);
m.invoke(o, null);
调用任意类的任意方法的演示:
public class TestInvokeAnything {
public static void main(String[] args) throws Exception {
// invokeAny() 执行任何方法
// 传入:对象(Object)、方法名称(String)、形参(.class)、实参(Object)
invokeAny(
createObject("com.day.t1_factory.Student"),
"exam",
new Class[] {int.class, double.class, String.class},
2, 10, "小明"
); // public void exam(int n, double score, String name)
Object o = createObject("com.day.t1_factory.Student");
invokeAny(o, "study", null, null); // public void study()
invokeAny(o, "study", new Class[] {Integer.class}, 100); // public int study(Integer a)
}
/**
* 反射技术,执行任何方法
* @param obj Objcet类型对象
* @param methodName String类型方法名称
* @param types Class[]数组类型的types
* @param args Object类型的可变长参数
* @throws Exception
*/
public static void invokeAny(Object obj, String methodName, Class<?>[] types, Object...args) throws Exception {
Class<?> c = obj.getClass(); // 1.获取类对象
Method m = c.getDeclaredMethod(methodName, types); // 2.获得方法的对象Method
m.invoke(obj, args); // 3.执行方法
}
/**
* 反射技术,工厂设计模式
* @param className 类的全限定名
* @return 返回Object类型的对象
*/
public static Object createObject(String className) {
try {
Class<?> c = Class.forName(className);
return c.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}