Investigating the Performance Impact of Java Reflection

This article presents a systematic benchmark of Java reflection versus direct method and field access, analyzes the measured latency across varying call counts, identifies the costly operations within reflection (such as getMethod, getDeclaredField, invoke, and set), and offers practical guidelines to mitigate reflection‑induced performance overhead.

Top Architect
Top Architect
Top Architect
Investigating the Performance Impact of Java Reflection

The author revisits a previous article on Java reflection and, prompted by reader questions, conducts a series of micro‑benchmarks to quantify how reflection affects execution time compared with ordinary method and field access.

Four access patterns are evaluated: direct method call, reflective method call, direct field access, and reflective field access. For each pattern the test iterates from 1 to 1,000,000 calls, averaging multiple runs to smooth out noise.

Below is the original Android activity used for the measurements (code lines are preserved inside

tags):</p>
<pre>
<code>public class ReflectionPerformanceActivity extends Activity {
private TextView mExecuteResultTxtView = null;
private EditText mExecuteCountEditTxt = null;
private Executor mPerformanceExecutor = Executors.newSingleThreadExecutor();
private static final int AVERAGE_COUNT = 10;
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_reflection_performance_layout);
        mExecuteResultTxtView = (TextView)findViewById(R.id.executeResultTxtId);
        mExecuteCountEditTxt = (EditText)findViewById(R.id.executeCountEditTxtId);
    }
public void onClick(View v) { ... }
private void execute() { ... }
private long getReflectCallMethodCostTime(int count) { ... }
private long getReflectCallFieldCostTime(int count) { ... }
private long getNormalCallCostTime(int count) { ... }
private long getNormalFieldCostTime(int count) { ... }
private void updateResultTextView(final String content) { ... }

The initial benchmark results show that reflection does introduce a measurable slowdown. When the number of invocations stays below about 100, the difference is negligible; beyond that threshold the gap widens dramatically. Among the four approaches, direct instance field access is fastest, followed by direct method call (≈1.4× slower), reflective field access (≈3.75× slower), and reflective method call (≈6.2× slower). To pinpoint the expensive part, the author isolates the invoke / set pair and the getMethod / getDeclaredField pair in separate tests. The revised methods are:

private long getReflectCallMethodCostTime(int count) {
    long startTime = System.currentTimeMillis();
    ProgramMonkey programMonkey = new ProgramMonkey("小明", "男", 12);
    Method setmLanguageMethod = null;
    try {
        setmLanguageMethod = programMonkey.getClass().getMethod("setmLanguage", String.class);
        setmLanguageMethod.setAccessible(true);
    } catch (NoSuchMethodException e) { e.printStackTrace(); }
    for (int i = 0; i < count; i++) {
        try { setmLanguageMethod.invoke(programMonkey, "Java"); }
        catch (IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); }
    }
    return System.currentTimeMillis() - startTime;
}
</code>
<code>private long getReflectCallFieldCostTime(int count) {
    long startTime = System.currentTimeMillis();
    ProgramMonkey programMonkey = new ProgramMonkey("小明", "男", 12);
    Field ageField = null;
    try { ageField = programMonkey.getClass().getDeclaredField("mLanguage"); }
    catch (NoSuchFieldException e) { e.printStackTrace(); }
    for (int i = 0; i < count; i++) {
        try { ageField.set(programMonkey, "Java"); }
        catch (IllegalAccessException e) { e.printStackTrace(); }
    }
    return System.currentTimeMillis() - startTime;
}

Running these benchmarks reveals that the reflective invoke and set operations are slower than the reflective lookup operations ( getMethod and getDeclaredField ), confirming that the actual invocation overhead dominates the performance penalty. Further experiments replace the reflective lookup with repeated calls to getMethod and getDeclaredField inside the loop, showing that the lookup itself also adds cost, though less than the invocation. Key conclusions drawn from the experiments:

Reflection does cause performance degradation, especially when used intensively.

The impact scales with the number of reflective calls; keeping reflective usage under roughly 100 calls makes the overhead negligible.

Direct instance field access is the most efficient, followed by direct method calls, reflective field access, and finally reflective method calls.

Both the reflective lookup (via getMethod / getDeclaredField) and the actual reflective invocation ( invoke / set) contribute to the slowdown, with the latter being the larger factor.

Practical recommendations to avoid reflection‑related performance issues include:

Limit the frequency and volume of reflective operations; cache Method and Field objects when repeated access is required.

Prefer direct field access over reflective method invocation when possible.

Consider alternative designs (e.g., interfaces, factories) that eliminate the need for reflection in performance‑critical paths.

The article ends with a brief outline of future test ideas, such as measuring the cost of repeated native calls, evaluating the effect of extensive conditional logic, and assessing how class complexity influences reflective performance.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaperformanceoptimizationAndroidBenchmark
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.