Java的getDeclaredField和getField的使用和区别,以及如何获取父类的私有字段

终于于于于于休息啦,上来先说结论。

结论:

  1. getDeclaredFields方法仅对类本身的字段有效果,对于继承的父类的字段无效
  2. getFields方法只能获取类及其父类的公共字段
  3. 获取父类的私有字段需要先使用getSuperClass获取父类Class,然后通过父类Class的getDeclaredFields方法获取父类的所有字段

 下面我们举个简单的栗子:

这是我们定义的一个父类,其中定义了一个公共字段superDesc,和一个私有字段superName

public class SuperModel {

	private String superName;
	public String superDesc;

	public String getSuperDesc() {
		return superDesc;
	}
	public void setSuperDesc(String superDesc) {
		this.superDesc = superDesc;
	}
	public String getSuperName() {
		return superName;
	}
	public void setSuperName(String superName) {
		this.superName = superName;
	}

}

这是我定义的一个子类,其中也定义了一个公共字段modelDesc和一个私有字段modelName

public class Model extends SuperModel {

	public String modelDesc;
	private String modelName;

	public String getModelDesc() {
		return modelDesc;
	}
	public void setModelDesc(String modelDesc) {
		this.modelDesc = modelDesc;
	}
	public String getModelName() {
		return modelName;
	}
	public void setModelName(String modelName) {
		this.modelName = modelName;
	}
}

下面我使用了三个测试方法来测试。

public class ReflectTest {
	public static void main(String[] args) {
		Model model = new Model();
		model.setSuperDesc("父类公开字段");
		model.setSuperName("父类私有字段");
		model.setModelDesc("子类公开字段");
		model.setModelName("子类私有字段");

		//通过getFields方法遍历字段获取model字段
		getNameByGetFields(model);

		//通过getDeclaredFeilds方法获取model字段
		getNameByDeclaredFields(model);

		//通过getSuperClass方法获取model字段
		getNameBySuperClass(model);
	}

	private static void getNameByGetFields(Model model) {
		Class<? extends Model> sonClass = model.getClass();
		try {
			Field[] fields = sonClass.getFields();
			System.out.println("通过getFields方法遍历字段获取model字段:       ");
			for (Field field : fields) {
				System.out.println(field.getName() + ":" + field.get(model));
			}
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}

	private static void getNameByDeclaredFields(Model model) {
		Class<? extends Model> sonClass = model.getClass();
		try {
			System.out.println("通过getDeclaredFeilds方法获取model字段:      ");
			Field[] fields = sonClass.getDeclaredFields();
			for (Field field : fields) {
				field.setAccessible(true);
				System.out.println(field.getName() + ":" + field.get(model));
			}
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}

	private static void getNameBySuperClass(Model model) {
		Class<? extends Model> sonClass = model.getClass();
		try {
			System.out.println("通过getSuperClass方法获取superName字段    ");
			Class<?> superclass = sonClass.getSuperclass();
			Field[] fields = superclass.getDeclaredFields();
			for (Field field : fields) {
				field.setAccessible(true);
				System.out.println(field.getName() + ":" + field.get(model));
			}
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}
}

 当我使用getFields方法遍历所有字段时,输出了以下信息:

这说明getFileds方法只能获取公共字段,但是可以同时获取本身和父类的公共字段

以下是JDK文档中的描述:


 当我使用getDecleadFields遍历所有字段时,输出了以下信息:

这说明getDecleadFields方法只能获取类本身的字段,但是不能获取父类的字段

以下时JDK文档中的描述:


当我使用getSuperClass获取父类Class后再使用父类的Class的getDecleadFields方法,不出所料,输出的父类所有的字段。

这说明要获取父类的私有字段必须先获取它的Class对象。而要遍历一个对象应该出现的所有字段,就需要遍历这个对象和这个对象的父类所有字段,不能一次性直接获取到所有字段。

最后给个分享个不错的JDK API在线文档地址,点过去进首页能发现惊喜哦。JDK8中文API在线文档

Over

 

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java 反射可以通过以下方式获取类的字段: ```java Class<?> superClass = targetClass.getSuperclass(); // 获取目标类的类 Field[] fields = superClass.getDeclaredFields(); // 获取类的所有字段 ``` 其中,`targetClass` 是目标类的 `Class` 对象,`superClass` 是目标类的类的 `Class` 对象,`fields` 是类的所有字段数组。使用 `getDeclaredFields()` 可以获取所有的字段,包括私有字段。如果只需要获取公有字段,则可以使用 `getFields()` 方法。如果需要获取指定名称的字段,则可以使用 `getDeclaredField(String name)` 方法或 `getField(String name)` 方法。 需要注意的是,如果类的字段私有的,则需要通过 `setAccessible(true)` 方法来设置其可见性,否则在获取其值时会抛出 `IllegalAccessException` 异常。完整代码如下: ```java public static void main(String[] args) { ChildClass child = new ChildClass(); Class<?> targetClass = child.getClass(); Class<?> superClass = targetClass.getSuperclass(); // 获取目标类的类 Field[] fields = superClass.getDeclaredFields(); // 获取类的所有字段 for (Field field : fields) { field.setAccessible(true); // 设置私有字段可见 try { System.out.println(field.getName() + " = " + field.get(child)); // 获取并输出字段的值 } catch (IllegalAccessException e) { e.printStackTrace(); } } } public static class ParentClass { private String parentField = "parentValue"; } public static class ChildClass extends ParentClass { private String childField = "childValue"; } ``` 输出结果为: ``` parentField = parentValue ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值