在Java的面向对象编程中,父子类继承关系下,子类的方法访问是常见需求。Class.class作为类的元信息载体,对象引用作为实例的指向,二者访问子类方法的逻辑存在明显差异,下面结合实际场景展开说明。

基础示例类定义
首先定义父类和子类,子类新增特有方法并重写父类方法,用于后续测试:
// 父类
class Parent {
public void parentMethod() {
System.out.println("父类方法执行");
}
}
// 子类
class Child extends Parent {
// 重写父类方法
@Override
public void parentMethod() {
System.out.println("子类重写的父类方法执行");
}
// 子类特有方法
public void childSpecialMethod() {
System.out.println("子类特有方法执行");
}
}通过对象引用访问子类方法
当对象引用的编译时类型为父类,实际指向子类实例时,遵循多态的规则:
- 如果子类重写了父类的方法,调用时会执行子类的重写版本
- 如果方法是子类特有、父类没有的,无法直接通过父类引用调用,需要向下转型
具体代码示例如下:
public class ReferenceTest {
public static void main(String[] args) {
// 父类引用指向子类实例
Parent parentRef = new Child();
// 调用重写方法,执行子类版本
parentRef.parentMethod(); // 输出:子类重写的父类方法执行
// 直接调用子类特有方法会编译报错
// parentRef.childSpecialMethod();
// 向下转型后调用子类特有方法
if (parentRef instanceof Child) {
Child childRef = (Child) parentRef;
childRef.childSpecialMethod(); // 输出:子类特有方法执行
}
}
}通过Class.class访问子类方法
Class.class是反射的入口,通过类对象可以获取类的所有方法信息,不受编译时类型限制:
- 可以通过
getDeclaredMethods()获取类自身声明的方法,包含私有、公有、重写和特有方法 - 可以通过
getMethods()获取类及其所有父类的公有方法
通过反射调用子类方法的代码示例:
import java.lang.reflect.Method;
public class ClassTest {
public static void main(String[] args) throws Exception {
// 获取子类的Class对象
Class<Child> childClass = Child.class;
// 获取子类声明的所有方法
Method[] declaredMethods = childClass.getDeclaredMethods();
System.out.println("子类声明的方法:");
for (Method method : declaredMethods) {
System.out.println(method.getName());
}
// 输出:parentMethod、childSpecialMethod
// 创建子类实例
Child child = childClass.newInstance();
// 调用重写方法
Method overrideMethod = childClass.getMethod("parentMethod");
overrideMethod.invoke(child); // 输出:子类重写的父类方法执行
// 调用子类特有方法
Method specialMethod = childClass.getMethod("childSpecialMethod");
specialMethod.invoke(child); // 输出:子类特有方法执行
}
}两种方式的核心差异对比
| 对比维度 | 对象引用访问 | Class.class反射访问 |
|---|---|---|
| 编译时校验 | 受编译时类型限制,无法直接调用父类没有的方法 | 不受编译时类型限制,运行时动态获取方法 |
| 方法调用范围 | 只能调用编译时类型存在的方法,或通过转型调用子类方法 | 可以获取并调用类自身及父类所有符合访问权限的方法 |
| 性能开销 | 无额外反射开销,性能更高 | 有反射调用开销,性能略低 |
| 适用场景 | 已知类型关系,常规业务逻辑调用 | 不确定具体类型,需要动态处理类方法的场景 |
注意事项
使用对象引用时,向下转型前务必通过instanceof判断类型,避免类型转换异常。使用Class.class反射时,要注意方法的访问权限,私有方法需要调用setAccessible(true)才能执行,同时反射调用需要处理非法访问、方法不存在等异常。实际开发中,优先选择对象引用的方式访问方法,只有在需要动态处理类型、框架开发等场景才使用反射的方式,兼顾代码的可读性和性能。
Class.class对象引用子类方法反射多态修改时间:2026-06-04 03:25:58