如何不调用单个Getter方法打印子类实例中父类A的全部属性?
解决方案:通过反射动态打印父类A的所有属性
要避免每次父类A新增属性就修改main方法,你可以利用Java的反射机制来动态获取并打印A的所有属性(或对应的getter返回值),无需硬编码每个getter调用。
方法1:直接访问父类的字段(适用于字段为public的场景)
你的代码中A的字段是public,可直接通过反射获取A的所有字段,读取实例值:
import java.lang.reflect.Field; public abstract class A { public String p1; public String p2; // Getters/Setters public String getP1() { return p1; } public void setP1(String p1) { this.p1 = p1; } public String getP2() { return p2; } public void setP2(String p2) { this.p2 = p2; } } public class B extends A { public String p3; public String p4; // Getters/Setters public String getP3() { return p3; } public void setP3(String p3) { this.p3 = p3; } public String getP4() { return p4; } public void setP4(String p4) { this.p4 = p4; } } public class Main { public static void main(String[] args) { // 初始化B实例并赋值 B b = new B(); b.setP1("Value of p1"); b.setP2("Value of p2"); b.setP3("Value of p3"); b.setP4("Value of p4"); // 获取父类A的Class对象 Class<?> parentClass = A.class; // 获取A的所有声明字段 Field[] fields = parentClass.getDeclaredFields(); for (Field field : fields) { try { // 读取字段值(public字段无需额外权限设置) Object value = field.get(b); System.out.printf("%s: %s%n", field.getName(), value); } catch (IllegalAccessException e) { e.printStackTrace(); } } } }
方法2:通过调用getter方法(更规范,适用于字段为private的场景)
如果后续A的字段改为private(符合封装规范),推荐通过反射调用getter方法获取值,避免直接访问字段:
import java.lang.reflect.Method; public class Main { public static void main(String[] args) { B b = new B(); b.setP1("Value of p1"); b.setP2("Value of p2"); b.setP3("Value of p3"); b.setP4("Value of p4"); Class<?> parentClass = A.class; Method[] methods = parentClass.getDeclaredMethods(); for (Method method : methods) { // 筛选getter方法:以"get"开头、无参数、返回值非void if (method.getName().startsWith("get") && method.getParameterCount() == 0 && !method.getReturnType().equals(Void.TYPE)) { try { Object value = method.invoke(b); // 从方法名提取属性名(比如getP1 -> p1) String fieldName = method.getName().substring(3); fieldName = fieldName.substring(0, 1).toLowerCase() + fieldName.substring(1); System.out.printf("%s: %s%n", fieldName, value); } catch (Exception e) { e.printStackTrace(); } } } } }
说明
- 两种方法都能动态适配A的属性变更:后续A新增属性(比如p5),只要添加对应字段和getter,main方法无需修改就能自动打印新增属性的值。
- 反射会带来少量性能开销,但绝大多数业务场景下可忽略。
- 若需处理int、boolean等其他类型属性,可在遍历中增加类型判断,调整打印格式。
内容的提问来源于stack exchange,提问作者Aditya Mahajan
相关产品推荐
相关产品推荐

