目录
[2. 反射成员方法](#2. 反射成员方法)
[3. 反射成员变量](#3. 反射成员变量)
[动态代理(Dynamic Proxy)](#动态代理(Dynamic Proxy))
反射Reflection,Java的反射是指程序在运行期可以拿到一个对象的所有信息,解决在运行期,对某个实例一无所知的情况下,如何调用其方法
Class类
只能由JVM创建的类,当JVM去加载某个class时,会new 一个Class实例 记录 该class的所有信息
我们可以通过这个Class
实例获取到该实例对应的class
的所有信息,即为 反射
获取Class实例
1.通过 某class 的静态变量 获取 Class实例
java
Class cls = String.class;
- 通过该实例变量提供的
getClass()
方法获取
java
String s = "Hello";
Class cls = s.getClass();
3.完整类名,可通过静态方法Class.forName()
获取
java
Class cls = Class.forName("java.lang.String");
Class
实例在JVM中是唯一的,所以,上述方法获取的Class
实例是同一个实例
动态加载
"一次编写,到处运行"
动态加载是指JVM在程序运行期间根据需要加载、链接和初始化类的机制,减少了程序的初始加载时间,只有真正使用到的类才会被加载
Commons Logging总是优先使用Log4j,只有当Log4j不存在时,才使用JDK的logging。利用JVM动态加载特性,大致的实现代码如下:
java
// Commons Logging优先使用Log4j:
LogFactory factory = null;
if (isClassPresent("org.apache.logging.log4j.Logger")) {
factory = createLog4j();
} else {
factory = createJdkLog();
}
boolean isClassPresent(String name) {
try {
Class.forName(name);
return true;
} catch (Exception e) {
return false;
}
}
Class的一些成员方法
1.反射实例
java
import java.lang.reflect.Constructor;
public class ReflectionNewInstance {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("java.util.Date");
// 方式1:调用无参构造(已过时)
Object obj1 = cls.newInstance();
System.out.println(obj1); // 当前日期
// 方式2:通过Constructor对象(推荐)
Constructor<?> constructor = cls.getConstructor();
Object obj2 = constructor.newInstance();
System.out.println(obj2); // 当前日期
// 方式3:调用有参构造
Constructor<?> strConstructor = String.class.getConstructor(String.class);
String str = (String) strConstructor.newInstance("Hello");
System.out.println(str); // Hello
}
}
newInstance()
已过时,推荐使用Constructor.newInstance()

2. 反射成员方法
java
import java.lang.reflect.Method;
public class InvokeMethodExample {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("java.lang.String");
Object str = cls.getConstructor(String.class).newInstance("Hello");
// 获取并调用方法
Method method = cls.getMethod("toUpperCase");
String result = (String) method.invoke(str);
System.out.println(result); // HELLO
// 调用私有方法(需设置accessible)
Method privateMethod = cls.getDeclaredMethod("indexOf", String.class, int.class);
privateMethod.setAccessible(true);
int index = (int) privateMethod.invoke(str, "l", 0);
System.out.println(index); // 2
}
}
getMethod
获取公共方法,getDeclaredMethod
可获取私有方法(需setAccessible(true)
)
调用 静态方法,invoke
方法传入的第一个参数永远为null


3. 反射成员变量
java
import java.lang.reflect.Field;
class Person {
private String name = "Alice";
}
public class FieldExample {
public static void main(String[] args) throws Exception {
Class<?> cls = Class.forName("Person");
Object obj = cls.newInstance();
// 获取并修改私有字段
Field field = cls.getDeclaredField("name");
field.setAccessible(true);
System.out.println(field.get(obj)); // Alice
field.set(obj, "Bob");
System.out.println(field.get(obj)); // Bob
}
}
4.反射类结构
getInterfaces()
只返回当前类直接实现的接口类型
两个Class
实例,要判断一个向上转型是否成立,可以调用isAssignableFrom()
java
class ClassStructure {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> cls = Class.forName("java.util.ArrayList");
// 获取类名和修饰符
System.out.println("Class: " + cls.getName());
System.out.println("Modifiers: " + Modifier.toString(cls.getModifiers()));
// 获取父类和接口
System.out.println("Superclass: " + cls.getSuperclass().getName());
for (Class<?> iface : cls.getInterfaces()) {
System.out.println("Implements: " + iface.getName());
}
ArrayList arrayList = new ArrayList<>();
System.out.println(arrayList instanceof List);
System.out.println(arrayList.getClass().isAssignableFrom(List.class));
System.out.println(List.class.isAssignableFrom(arrayList.getClass()));
}
}
动态代理(Dynamic Proxy)
动态代理:绕过interface的实现类 ,可以在运行期动态创建某个interface
的实例
静态代码 就是 编写接口的实现类,然后自动向上转型赋值
java
public interface Hello {
void morning(String name);
}
public class HelloWorld implements Hello {
public void morning(String name) {
System.out.println("Good morning, " + name);
}
}
Hello hello = new HelloWorld();
hello.morning("Bob");
简单实现动态代理
java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Main {
public static void main(String[] args) {
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method);
if (method.getName().equals("morning")) {
System.out.println("Good morning, " + args[0]);
}
return null;
}
};
Hello hello = (Hello) Proxy.newProxyInstance(
Hello.class.getClassLoader(), // 传入ClassLoader
new Class[] { Hello.class }, // 传入要实现的接口
handler); // 传入处理调用方法的InvocationHandler
hello.morning("Bob");
}
}
interface Hello {
void morning(String name);
}
上面的动态代理改写为静态实现类大概长这样:
java
public class HelloDynamicProxy implements Hello {
InvocationHandler handler;
public HelloDynamicProxy(InvocationHandler handler) {
this.handler = handler;
}
public void morning(String name) {
handler.invoke(
this,
Hello.class.getMethod("morning", String.class),
new Object[] { name }
);
}
}
动态代理是通过Proxy
创建代理对象,然后将接口方法"代理"给InvocationHandler
完成的。