反射和设计模式
一、反射
1. 相关概念
· 类的对象:基于类创建的实例(通过 new 创建)。
· 类对象:类加载的产物,封装了类的所有信息(包名、类名、父类、接口、属性、方法、构造方法)。
· 反射:通过反射获取类的类对象,从而获取类的信息并进行操作。
2. 获取类对象的三种方式
· 通过 Object 类的 getClass() 方法:
```java
Student s = new Student(); // 类的对象
Class c1 = s.getClass(); // 类对象
```
· 通过 类名.class:
```java
Class c2 = Student.class;
```
· 通过 Class.forName("包名.类名"):
```java
Class c3 = Class.forName("test_flect.Student");
```
注意:参数需为全类名(包名.类名),否则抛出 ClassNotFoundException。
3. 类加载的时机
· 第一次创建该类对象
· 第一次使用该类的静态成员(静态属性/方法)
· 子类加载会导致父类先加载
· 通过反射获取类对象时
4. 常用方法
· getName():获取类名
· getMethods():获取本类+父类所有公开方法
· getDeclaredMethods():获取本类所有方法(含非公开)
· 通过类对象创建类的对象(无参):
```java
Class c = Class.forName("test_flect.Student");
Object obj = c.newInstance(); // 默认调用无参构造
```
需提供无参构造,否则抛 InstantiationException。
· 通过有参构造创建对象:
```java
Constructor constructor = c.getConstructor(String.class, Integer.class);
Object o = constructor.newInstance("方青", 48);
```
· 调用方法(含私有):
```java
Method m = c.getDeclaredMethod("test");
m.setAccessible(true); // 打破封装
m.invoke(o);
```
5. 反射的优缺点
· 缺点:可读性差、代码繁琐、打破封装
· 优点:代码更通用灵活,常用于底层架构(如框架)
—
二、设计模式(23种)
1. 设计模式:被反复使用、分类编目的代码经验总结。
2. 单例设计模式(保证VM内仅存在该类的一个实例)
· 饿汉式:
```java
class ClassA {
private static final ClassA ca = new ClassA();
private ClassA() {}
public static ClassA getInstance() {
return ca;
}
}
```
· 优点:线程并发效率高
· 缺点:空间利用率较低
· 懒汉式:
```java
class ClassB {
private static ClassB cb;
private ClassB() {}
public synchronized static ClassB getInstance() {
if (cb == null) {
cb = new ClassB();
}
return cb;
}
}
```
· 优点:空间利用率较高
· 缺点:线程并发效率低
· 第三种方式(静态内部类):
```java
class ClassC {
private ClassC() {}
private static class Inner {
final static ClassC c = new ClassC();
}
public static ClassC getInstance() {
return Inner.c;
}
}
```
3. 工厂设计模式
· 用于解决对象创建问题,通常结合反射技术使工厂通用灵活。
· 扩充:Properties 是 Hashtable 的子类,键值默认为 String:
· load(InputStream in) / load(Reader in):加载配置文件,按 = 或 : 拆分键值对
· String getProperty(String key):通过键获取值





