Java 反射:揭开方法和构造函数的神秘面纱
Java 反射:揭开方法和构造函数的神秘面纱
在 Java 编程的世界中,反射(Reflection)是一项强大而神秘的技术。它允许我们在运行时检查和操作类、方法、字段等,甚至可以调用私有方法或访问私有字段。然而,反射的强大之处也伴随着一些容易混淆的概念,比如 getMethods() 和 getDeclaredMethods() 方法的区别,以及构造函数在反射中的特殊地位。
问题引入:方法数组的长度差异
假设我们有一个 User 类,其中包含一些公共和私有的方法。我们希望通过反射来获取这些方法,并观察它们的差异。于是,我们编写了以下测试代码:
public class MethodDemo1 {
@Test
public void testMethods(){
try {
Class clazz = Class.forName("com.itcq.reflect.method.User");
Method[] methods = clazz.getMethods();
System.out.println(methods.length);
for (Method method : methods) {
System.out.println(method.getName()+"---"+method.getParameterCount());
}
System.out.println("-----------------------------------------------");
Method[] declaredMethods = clazz.getDeclaredMethods();
System.out.println(declaredMethods.length);
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod.getName()+"---"+declaredMethod.getParameterCount());
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
运行结果显示,methods 数组的长度比 declaredMethods 数组的长度要长。这是为什么呢?
深入解析:方法与声明方法的区别
1. getMethods() 方法
getMethods() 方法返回的是类中所有 公共 方法的数组。这些方法不仅包括类本身声明的公共方法,还包括从父类继承而来的公共方法。因此,methods 数组中包含了所有可以访问的公共方法。
2. getDeclaredMethods() 方法
getDeclaredMethods() 方法则返回类中 声明的 所有方法,无论这些方法的访问修饰符是什么(public、private、protected)。但它只关注类本身声明的方法,不包括继承而来的方法。
疑问解答:为什么没有获取到构造函数?
在 Java 反射中,方法和构造函数是两种不同的成员类型。虽然 public User() 是一个公共的构造方法,但 getMethods() 和 getDeclaredMethods() 方法并不会直接返回构造函数。
1. 构造函数的特殊性
构造函数在 Java 中具有以下特殊性:
- 名字与类名相同: 构造函数的名字必须与类名完全一致。
- 没有返回值: 构造函数没有返回值,甚至连
void都不需要。 - 自动调用: 当创建一个对象时,系统会自动调用构造函数,不需要显式调用。
- 初始化对象: 构造函数的主要作用是初始化对象的数据成员,为对象分配内存并设置初始值。
2. 获取构造函数的方法
要获取构造函数,需要使用 getConstructors() 或 getDeclaredConstructors() 方法。前者获取公共构造函数,后者获取所有声明的构造函数。
Constructor[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
对比 C++:构造函数也是成员函数
在 C++ 中,构造函数的确算作成员函数。它们具有成员函数的一些共同特点:
- 属于类: 构造函数与其他成员函数一样,都属于某个特定的类,是类的一部分。
- 作用域: 构造函数的作用域与其他成员函数一样,都限定在类的内部。
- 访问权限: 构造函数可以有
public、private、protected等不同的访问权限,就像其他成员函数一样。
然而,构造函数也有一些特殊之处,使其与普通成员函数有所区别:
- 名字与类名相同: 构造函数的名字必须与类名完全一致。
- 没有返回值: 构造函数没有返回值,甚至连
void都不需要。 - 自动调用: 当创建一个对象时,系统会自动调用构造函数,不需要显式调用。
- 初始化对象: 构造函数的主要作用是初始化对象的数据成员,为对象分配内存并设置初始值。
总结
Java 的反射机制将方法和构造函数区分对待,所以获取它们的方式也不同。如果你想全面了解一个类的结构,需要同时使用 getMethods()、getDeclaredMethods()、getConstructors() 和 getDeclaredConstructors() 这几个方法。
通过本文的解析,相信你对 Java 反射中的方法和构造函数有了更清晰的认识。反射虽然强大,但也需要我们仔细理解其背后的机制,才能更好地利用它来解决实际问题。
浙公网安备 33010602011771号