转自: http://www.blogjava.net/jjwwhmm/archive/2008/06/19/209083.html
下面这个例子在实际项目中一般都不会这么用,只是用来说明怎么通过反射修改类的私有字段的值.
有一个类TestData:
public class TestData {
private String name = "1";
public String getName() {
return name;
}
}
在运行的时候怎么来修改name的值呢?
public class TestReflection extends TestCase {
public void testSetPrivateField() throws Exception {
TestData data = new TestData();
System.out.println(data.getName());
Assert.assertEquals("1", data.getName());
Field f = data.getClass().getDeclaredField("name");
f.setAccessible(true);
f.set(data, "2");
System.out.println(data.getName());
Assert.assertEquals("2", data.getName());
}
}
运行结果:
1
2
其中,最关键的代码是:
f.setAccessible(true);
这行代码把对象data上的name字段设置为public访问属性.
既然私有字段可以这样访问,那么,类似的,私有方法也可以这样调用!
改一下TestData:
public class TestData {
private String name = "1";
public String getName() {
return name;
}
private void setName(String name) {
this.name = name;
}
}
在TestData中增加了私有的setName方法,下面是测试代码:
public class TestReflection extends TestCase {
public void testInvokePrivateMethod() throws Exception {
TestData data = new TestData();
System.out.println(data.getName());
Assert.assertEquals("1", data.getName());
Method m = data.getClass().getDeclaredMethod("setName", String.class);
m.setAccessible(true);
m.invoke(data, "3");
System.out.println(data.getName());
Assert.assertEquals("3", data.getName());
}
}
运行结果:
1
3
其中最关键的代码行是:
m.setAccessible(true);
它把对象data的setName方法的访问属性设置为public.
那么这样调用私有方法,访问私有属性有什么用处呢?
在实际项目中,我们会使用很多其它第三方的包,有的时候是通过修改源代码完成你想要的功能,有的时候,是因为第三方包中仅仅因为某几个方法的访问属性被设置为private,或者只要修改private的字段值即可.这个时候,用这种反射的方法就可以很容易实现了.
另外一个场景就是从系统架构层来考虑数据封装.例如系统有一些元数据类,99%的情况下,我们只是提供get方法供其它应用层获得字段的值,如果把修改的set方法也提供出去,那么可能会影响到系统的可维护性.而在系统运行期间,又很难避免的要修改这些元数据的值.这种情况下,也可以通过这种反射的方式来实现.
分享到:
相关推荐
总结起来,Java反射为我们提供了在运行时操作类、方法和属性的强大工具,包括调用私有方法和获取私有属性值。然而,它也是一把双刃剑,使用时需权衡利弊,确保代码的稳定性和安全性。在处理私有成员时,务必注意对...
当需要使用反射调用某个对象的方法或访问其字段时,可以通过Frida的`Java.use`方法获取到对应的类的代理对象,然后通过调用其方法来实现。例如,在Frida脚本中可以使用`classObject.getDeclaredField("fieldName")....
- **设置私有字段的值**:使用`SetValue`方法将`myValue`字段的值从“old value”更改为“new value”。 #### 2.3 深入理解 - **`BindingFlags`标志**:`BindingFlags`是一个枚举类型,用于指定如何搜索要访问的...
Java反射是Java编程语言中的一个强大特性,它允许在运行时检查类、接口、字段和方法的信息,并且能够在运行时动态地创建对象和调用方法。这个特性使得Java具有了高度的灵活性,常用于框架开发、插件系统、元编程等...
2. **访问私有成员**:通过反射,我们可以访问类的私有字段和方法,这在单元测试、调试或某些特定场景下可能需要。`Method`类提供了`getDeclaredMethod()`方法来获取类的私有方法,而`invoke()`方法则可以用来调用这...
例如,`Method`类的`setAccessible(true)`方法可以将某个方法或字段设置为可访问,从而可以调用私有方法或修改私有属性。这在测试、调试或者特定场景下很有用,但也要谨慎使用,因为它破坏了封装性,可能引入安全...
为了访问私有字段,我们需要调用`setAccessible(true)`方法,使得我们可以绕过Java的访问控制规则。 ```java for (Field field : fields) { if ("myPrivateField".equals(field.getName())) { field....
要调用私有方法,我们需要使用`Method`类,先获取到该方法的`Method`对象,然后通过`setAccessible(true)`将其访问权限设为可访问,最后通过`invoke()`方法调用: ```java Method privateMethod = personClass....
这些代码可能包括创建枚举类,然后通过反射获取枚举值、实例名以及演示如何使用`getDeclaredConstructor()`和`newInstance()`方法来访问私有构造函数(虽然这不是常规用法)。 通过深入理解这些概念,你可以更好地...
反射机制使得我们能够在运行时动态地获取类的信息,并且能够创建对象、调用方法、访问字段,甚至改变类的行为。在Java中,`java.lang.reflect`包提供了对反射的支持。 在“反射,动态加载指定类调用类中的方法”这...
7. 调用私有方法,传递参数并捕获结果。例如,`setMethod.invoke(child, new Integer(10))` 8. 验证结果,检查是否符合预期。可以使用断言库,如JUnit提供的`assertThat()`。 请注意,尽管反射可以让我们访问私有...
在Java编程中,反射是一种强大的工具,它允许我们在运行时检查和操作类、接口、字段以及方法等对象。本文将详细讲解如何通过反射调用静态方法,并探讨在特定场景下,如MyBatis中的应用。 首先,理解反射的概念是至...
通过反射,可以动态地获取类的信息并操作其字段、方法以及构造器等。本文将详细介绍如何利用反射机制访问和实例化一个私有的内部类,并通过代码示例进行说明。 #### 二、反射概述 反射是Java语言提供的一种能够在...
在Java中,反射机制主要用于以下几种情况:动态加载类、访问私有成员、运行时检查类型以及调用私有方法等。 标题“Java反射机制修改私有成员变量的实现_Reflection”着重讲述了如何利用反射来修改私有成员变量的值...
Java反射是Java语言提供的一种强大的动态类型特性,它允许程序在运行时检查和操作类、接口、对象等的内部信息,包括但不限于获取类的方法、字段、构造器等,并能动态调用方法和修改字段值。这个特性使得Java具有了更...
在Java或.NET编程环境中,反射是一种强大的工具,它允许程序在运行时检查并操作类、接口、字段和方法等对象。反射获取属性和调用方法是其核心功能,广泛应用于框架设计、动态代理、插件机制等领域。下面将详细解释这...
在Java编程语言中,反射是一种强大的机制,它允许程序在运行时检查类、接口、字段和方法的信息,并且能够动态地调用方法或修改字段值。本文将深入探讨如何通过反射来获取一个类中的所有属性及其对应的值,从而更好地...
本文将深入探讨如何利用Java反射来访问并修改类的私有字段。 #### 反射的基本概念 反射提供了以下主要功能: - 获取类的信息,如包名、类名等。 - 创建对象实例。 - 调用方法。 - 访问和修改字段。 - 构造器信息...
在本文中,我们将通过一个示例程序来解释C#类继承中的私有字段是如何实现的,并探讨它们在内存中的布局。 首先,让我们看一个示例程序: ```csharp internal class Program { static void Main(string[] args) {...