反射
在编译期间,并不清楚应该加载哪个类,类的加载是在运行期间进行的。通过反射,可以对类进行加载、探知、自审。
反射起源
来自Class。Class是类模板,使用同一个Class类模板创建的不同的对象,拥有相同的属性和方法。
//获取Class对象
//第一种:类名.Class
Class c1 = Dog.class;
//第二种:对象.getClass()
Class c2 = dog1.getClass();
//第三种:Class.forName("类全路径(包名+类名)")
try {
Class c3 = Class.forName("com.lovo.reflexproject.Dog");
System.out.println(c2 == c3);//ture
System.out.println(c1 == c2);//ture
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//通过反射,自审类的属性和方法
Class c = Dog.class;
//得到该类中,共有属性的列表
// Field[] fs = c.getFields();
// System.out.println(fs);
//得到该类中,所有定义属性的列表
Field[] fs = c.getDeclaredFields();
for (Field f : fs) {
//得到属性名
System.out.println(f.getName());
}
System.out.println("--------------");
//得到该类公有方法列表,包括继承共有方法
// Method[] ms = c.getMethods();
//得到该类定义的所有方法列表,不包括继承的方法
Method[] ms = c.getDeclaredMethods();
for (Method m : ms) {
System.out.println(m.getName());
}
//根据属性名和方法名获取属性和方法
Class c = Dog.class;
Dog d1 = new Dog();
try {
//根据属性名,得到属性对象
Field f = c.getDeclaredField("age");
//根据方法名,得到方法对象
Method m = c.getMethod("speak");
//执行指定对象的方法
m.invoke(d1);
} catch (Exception e) {
e.printStackTrace();
}
//通过类的全路径打印类的方法
String str = JOptionPane.showInputDialog(null, "输入类的全路径");
try {
//加载类,得到类模板
Class c = Class.forName(str);
Method[] ms = c.getMethods();
for (Method n : ms) {
System.out.println(n.getName());
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Class c = Dog.class;
try {
//调用该类中的无参构造方法,产生对象
Object obj = c.getConstructor().newInstance();
} catch (Exception e) {
e.printStackTrace();
}
工厂模式
将对象的创建和对象的使用分开进行,其主要目的是解耦。
public class Factory {
private static Properties pro = new Properties();
static {
try {
pro.load(new FileReader("src/main/resources/dao.txt"));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 根据接口名称,得到实现类对象
*
* @param interfaceName
* @return
*/
public static Object getDAO(String interfaceName) {
//根据键,得到值,值是实现类全路径
String value = pro.getProperty(interfaceName);
try {
//加载类,得到类模板
Class c = Class.forName(value);
//调用无参构造方法,产生对象
return c.getConstructor().newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
1、定义接口
2、创建配置文件,描述接口和实现类的关系
3、创建工厂类,根据接口名,得到实现类对象
4、调用工厂类的工厂方法,得到接口实现类对象