Does creating an object using reflection rather than calling the class constructor result in any significant performance differences?
-
Related: [Any way to further optimize Java reflective method invocation?](https://stackoverflow.com/questions/414801/any-way-to-further-optimize-java-reflective-method-invocation) – Vadzim May 23 '19 at 21:40
14 Answers
Yes - absolutely. Looking up a class via reflection is, by magnitude, more expensive.
Quoting Java's documentation on reflection:
Because reflection involves types that are dynamically resolved, certain Java virtual machine optimizations can not be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.
Here's a simple test I hacked up in 5 minutes on my machine, running Sun JRE 6u10:
public class Main {
public static void main(String[] args) throws Exception
{
doRegular();
doReflection();
}
public static void doRegular() throws Exception
{
long start = System.currentTimeMillis();
for (int i=0; i<1000000; i++)
{
A a = new A();
a.doSomeThing();
}
System.out.println(System.currentTimeMillis() - start);
}
public static void doReflection() throws Exception
{
long start = System.currentTimeMillis();
for (int i=0; i<1000000; i++)
{
A a = (A) Class.forName("misc.A").newInstance();
a.doSomeThing();
}
System.out.println(System.currentTimeMillis() - start);
}
}
With these results:
35 // no reflection
465 // using reflection
Bear in mind the lookup and the instantiation are done together, and in some cases the lookup can be refactored away, but this is just a basic example.
Even if you just instantiate, you still get a performance hit:
30 // no reflection
47 // reflection using one lookup, only instantiating
Again, YMMV.

- 1,891
- 8
- 23
- 40

- 161,610
- 92
- 305
- 395
-
5On my machine the .newInstance() call with only one Class.forName() call scores 30 or so. Depending on VM version, the difference may be closer than you think with an appropriate caching strategy. – Sean Reilly Jan 13 '09 at 20:14
-
On my system (a dual core 2.4 GHz), I see times of - Instantiate: 7.8, Reflect 1: 171.9, and Reflect 2: 3181.3 (where reflect 2 is the reflection as above, and 1 is the reflection with forName done only once - all times are for 1,000,000 iterations). – Lawrence Dol Jan 13 '09 at 20:27
-
Also, this performance factor depends very much on the cost of the object initialization - i.e. the work done in the constructor. – Lawrence Dol Jan 13 '09 at 22:19
-
Generally you would use it to instantiate an object once and hold onto the instance. It wouldn't be a good idea for something you do 100 times or more a second, but then when you are doing anything more than 100x a second you should pay attention to it. Once you've instantiated the object, using it is no worse (unless you are accessing the methods via reflection as well). I'm just glad reflection is hard enough to scare away many people. Ruby it's really easy... makes it very heavily used--and makes me a little nervous. – Bill K Dec 01 '10 at 19:30
-
63@Peter Lawrey below pointed out that this test was completely invalid because the compiler was optimizing out the non-reflective solution (It can even prove that nothing is done and optimize out the for loop). Needs to be re-worked and should probably be removed from S.O. as bad / misleading information. Cache the created objects in an array in both cases to prevent the optimizer from optimizing it out. (It can't do this in the reflective situation because it can't prove that the constructor doesn't have side-effects) – Bill K May 05 '11 at 21:47
-
6@Bill K - let's not get carried away. Yes, the numbers are off due to optimizations. No, the test is **not** completely invalid. I added a call that removes any possibility of skewing the result, and the numbers are still stacked against reflection. In any case, remember that this is a very crude micro-benchmark which just shows that reflection always incurs a certain overhead – Yuval Adam May 05 '11 at 23:23
-
@YuvalAdam Of course it incurs an overhead that someone should be aware of if doing anything inside a loop of a million iterations or more, of course at that point you must take into consideration the evils of object instantiation and string contatenation as well--and none of these should be considered until we are doing them inside a loop of a million or more (and probably not even then!) – Bill K May 25 '12 at 23:23
-
4This is probably a useless benchmark. Depending on what doSomething does. If it does nothing with visible side effect, then your benchmark runs only dead code. – nes1983 May 26 '12 at 10:13
-
1Benchmark is not taking into consideration JVM warmup / compilation phase. Wrap main's content in a loop, and you'll see completely different numbers on subsequent runs. – Mike Nov 06 '12 at 17:11
-
11I just witnessed the JVM optimizing reflection 35 fold. Running the test repeatedly in a loop is how you test optimized code. First iteration: 3045ms, second iteration: 2941ms, third iteration: 90ms, fourth iteration: 83ms. Code: c.newInstance(i). c is a Constructor. Non reflective code: new A(i), which yields 13, 4, 3.. ms times. So yes, reflection in this case was slow, but not nearly as much slower as what people are concluding, because every test I'm seeing, they're simply running the test once without giving the JVM the opportunity to replace byte codes with machine code. – Mike Nov 06 '12 at 17:42
-
@Mike, according to your numbers, Reflection is even worse than it comes off in Yuvals test - instead of a factor of 13x slower, your initial numbers are 234x slower, and instead of 1.6x slower for optimized, your numbers indicate that reflection is 27x(!) slower. In other words, according to your numbers, it's not only "nearly as much slower than what people are concluding", it's MUCH MUCH slower than what people are concluding. – Torque May 19 '14 at 12:10
-
@Torque, that could be. After all, the re-compiled "warmed up" code benefits the non-reflection version much more. With reflection, it spends most of its time inside the libraries. – Mike Jun 17 '14 at 18:27
-
3Note that `System.currentTimeMillis()` *cannot* be used for a benchmark like this because of its common granularity in the order of 10-20ms! `System.nanoTime()` should be used, or the loop count increased by a factor of 100 or more. – JimmyB Sep 18 '14 at 07:34
-
4use JMH for all your microbenchmarks, i suggest to remove your benchmark code here because it is misleading – leozilla Apr 01 '16 at 18:08
Yes, it's slower.
But remember the damn #1 rule--PREMATURE OPTIMIZATION IS THE ROOT OF ALL EVIL
(Well, may be tied with #1 for DRY)
I swear, if someone came up to me at work and asked me this I'd be very watchful over their code for the next few months.
You must never optimize until you are sure you need it, until then, just write good, readable code.
Oh, and I don't mean write stupid code either. Just be thinking about the cleanest way you can possibly do it--no copy and paste, etc. (Still be wary of stuff like inner loops and using the collection that best fits your need--Ignoring these isn't "unoptimized" programming, it's "bad" programming)
It freaks me out when I hear questions like this, but then I forget that everyone has to go through learning all the rules themselves before they really get it. You'll get it after you've spent a man-month debugging something someone "Optimized".
EDIT:
An interesting thing happened in this thread. Check the #1 answer, it's an example of how powerful the compiler is at optimizing things. The test is completely invalid because the non-reflective instantiation can be completely factored out.
Lesson? Don't EVER optimize until you've written a clean, neatly coded solution and proven it to be too slow.

- 62,186
- 18
- 105
- 157
-
31I totally agree with the sentiment of this response, however if you're about to embark upon a major design decision it helps to have an idea about performance so you don't go off on a totally unworkable path. Maybe he's just doing due diligence? – Limbic System Feb 13 '09 at 23:51
-
29-1: Avoiding doing things the wrong way is not optimisation, it is just doing things. Optimisation is doing things the wrong, complicated way because of either real or imaginary performance concerns. – soru Jul 24 '10 at 11:06
-
5@soru totally agree. Choosing a linked list over an array list for an insertion sort is simply the right way to do things. But this particular question--there are good use cases for both sides of the original question, so choosing one based on performance rather than the most usable solution would be wrong. I'm not sure we are disagreeing at all, so I'm not sure why you said "-1". – Bill K Jul 26 '10 at 17:35
-
1Because you shouldn't mention performance as an issue at all until it has been established as the right thing to do. In this context, constructor for objects inside your type-checking/compilation 'world', reflection for things outside it. Performance is like price, just because something is expensive doesn't in itself make it better. A $10 digital watch probably tells the time as well or better than a $30,000 platinum chunk of bling. – soru Jul 28 '10 at 11:13
-
@soru that's exactly what I said. Still not sure why you feel we are disagreeing. Did you possibly misread my post? "You must never optimize until you are sure you need it" == "you shouldn't mention performance as an issue at all until it has been established as the right thing to do." – Bill K Jul 28 '10 at 17:51
-
15Any sensible analyst programmers needs to consider efficiency at an early stage or you might end up with a system that can NOT be optimised in an efficient and costworthy timeframe. No, you dont optimise every clock cycle but you most certainly DO employ best practices for something as basic as class instantiation. This example is a great one of WHY you consider such questions regarding reflection. It would be a pretty poor programmer who went ahead and used reflection throughout a million line system only to later discover it was orders of magnitude too slow. – RichieHH Aug 15 '10 at 14:51
-
2@Richard Riley Generally class instantiation is a pretty rare event for the selected classes you will use reflection on. I suppose you are right though--some people might instantiate every class reflectively, even ones that are recreated constantly. I would call that pretty bad programming (although even then you COULD implement a cache of class instances for reuse after the fact and not harm your code too much--so I guess I'd still say ALWAYS design for readability, then profile and optimize later) – Bill K Aug 16 '10 at 19:35
-
1-1: Considering the simplicity and genericity of the question, this answer is just noise... Even if I share your sentiments :) – Lukas Eder Dec 29 '11 at 20:09
-
2@LukasEder As with the questions "What is the best way to commit suicide" or "How do I best aim this bow to shoot the apple off my sister's head", the direct answer does not solve the underlying problem exposed by the question's existence and may in all likelyhood exasperate it--possibly resulting in someone getting hurt! – Bill K May 25 '12 at 23:34
-
Yes, avoid premature optimization, but that doesn't answer the question. There are definitely times when the answer matters. – Christopher Barber Oct 24 '12 at 23:13
-
@Christopher, didn't "Yes it's slower" answer the question? I gave the answer all the significance I thought it deserved--I put it at the top and made it brief in order to enhance the real point that if you are thinking about optimization in this way you are almost certainly Doing It Wrong--but I did answer... – Bill K Oct 25 '12 at 20:05
-
Disagree partially. Frequently it is necessary to think of performance at design time, the world is full off bloaty java APIs/Standards which perform poorly because of following this rule. Some things can't be optimized that easy at late stages of a project. – R.Moeller Dec 09 '12 at 18:22
-
@user1870904 Also, all I suggested was code it well, unit test it for performance and then fix it if it performs below some set bar. I never said leave it until the end of the project or ignore it altogether. The first pass through, coding it as clearly as you can, will improve your optomized code and give you known good unit tests. You really have a problem with this? – Bill K Dec 10 '12 at 17:05
-
The full quotation is"We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. A good programmer will not be lulled into complacency by such reasoning, he will be wise to look carefully at the critical code; but only after that code has been identified" - Donald Knuth – Ryan Feb 22 '13 at 18:03
-
@Ryan I believe that is nearly exactly what I was saying--I rephrased the rest but left out none of the sentament of the original quote. – Bill K Feb 22 '13 at 20:55
-
quite right, to worry about performance during coding time makes more trouble then solving. – Korben Nov 06 '18 at 06:10
You may find that A a = new A() is being optimised out by the JVM. If you put the objects into an array, they don't perform so well. ;) The following prints...
new A(), 141 ns
A.class.newInstance(), 266 ns
new A(), 103 ns
A.class.newInstance(), 261 ns
public class Run {
private static final int RUNS = 3000000;
public static class A {
}
public static void main(String[] args) throws Exception {
doRegular();
doReflection();
doRegular();
doReflection();
}
public static void doRegular() throws Exception {
A[] as = new A[RUNS];
long start = System.nanoTime();
for (int i = 0; i < RUNS; i++) {
as[i] = new A();
}
System.out.printf("new A(), %,d ns%n", (System.nanoTime() - start)/RUNS);
}
public static void doReflection() throws Exception {
A[] as = new A[RUNS];
long start = System.nanoTime();
for (int i = 0; i < RUNS; i++) {
as[i] = A.class.newInstance();
}
System.out.printf("A.class.newInstance(), %,d ns%n", (System.nanoTime() - start)/RUNS);
}
}
This suggest the difference is about 150 ns on my machine.

- 525,659
- 79
- 751
- 1,130
-
so you've just killed the optimiser, so now both versions are slow. Reflection is, therefore, still damn slow. – gbjbaanb Feb 13 '09 at 23:39
-
14@gbjbaanb if the optimizer was optimizing out the creation itself then it wasn't a valid test. @Peter's test is therefore valid because it actually compares the creation times (The optimizer wouldn't be able to work in ANY real-world situation because in any real-world situation you need the objects you are instantiating). – Bill K May 05 '11 at 21:43
-
10@nes1983 In which case you could have taken the opportunity to create a better benchmark. Perhaps you can offer something constructive, like what should be in the body of the method. – Peter Lawrey May 26 '12 at 15:05
-
1on my mac, openjdk 7u4, the difference is 95ns versus 100ns. Instead of storing A's in the array, I store hashCodes. If you say -verbose:class you can see when hotspot generates bytecode for constructing A and the accompanying speedup. – Ron May 26 '12 at 18:33
-
1@PeterLawrey If I lookup once (one call to`Class.getDeclaredMethod`) and then call `Method.invoke` multiple times? **Am I using reflection once or as many times as I invoke it?** Follow up question, what if instead of `Method` it is a `Constructor` and I do `Constructor.newInstance` multiple times? – tmj Jul 29 '15 at 14:47
-
@tMJ you are using reflection as many times as you call it. As the JVM warms up this will get more efficient over time but the reflection is still there. – Peter Lawrey Jul 29 '15 at 15:06
-
Then why the time difference, in @Yuval 's answer above, in case of *one `lookup` and multiple use* quite lower than ~150ns? Or is he again hitting some sort of optimization (I'm guessing not)? – tmj Jul 29 '15 at 15:12
-
@tMJ 150 ns sounds like a long time. A simple method call takes about 50 ns and after inlining it might not take any time at all. I would hope reflaction is not that slow for simple cases at least. – Peter Lawrey Jul 29 '15 at 15:14
-
@tMJ to give you some context, I am working if a persistence library which takes 75 ns to read/write a small indexed message. You can do a lot in that amount if time. – Peter Lawrey Jul 30 '15 at 05:11
-
Just for fun I run your "test" on an Android nexus 9. I wasn't expecting this : new A(), 146 ns A.class.newInstance(), **1 356 ns** new A(), 187 ns A.class.newInstance(), **1 374 ns** – AxelH Sep 02 '15 at 14:01
-
@AxelH some aspects of the JIT on Android are not as heavily optimised. – Peter Lawrey Sep 02 '15 at 14:15
If there really is need for something faster than reflection, and it's not just a premature optimization, then bytecode generation with ASM or a higher level library is an option. Generating the bytecode the first time is slower than just using reflection, but once the bytecode has been generated, it is as fast as normal Java code and will be optimized by the JIT compiler.
Some examples of applications which use code generation:
Invoking methods on proxies generated by CGLIB is slightly faster than Java's dynamic proxies, because CGLIB generates bytecode for its proxies, but dynamic proxies use only reflection (I measured CGLIB to be about 10x faster in method calls, but creating the proxies was slower).
JSerial generates bytecode for reading/writing the fields of serialized objects, instead of using reflection. There are some benchmarks on JSerial's site.
I'm not 100% sure (and I don't feel like reading the source now), but I think Guice generates bytecode to do dependency injection. Correct me if I'm wrong.

- 73,184
- 17
- 117
- 128
"Significant" is entirely dependent on context.
If you're using reflection to create a single handler object based on some configuration file, and then spending the rest of your time running database queries, then it's insignificant. If you're creating large numbers of objects via reflection in a tight loop, then yes, it's significant.
In general, design flexibility (where needed!) should drive your use of reflection, not performance. However, to determine whether performance is an issue, you need to profile rather than get arbitrary responses from a discussion forum.

- 38,754
- 10
- 77
- 102
There is some overhead with reflection, but it's a lot smaller on modern VMs than it used to be.
If you're using reflection to create every simple object in your program then something is wrong. Using it occasionally, when you have good reason, shouldn't be a problem at all.

- 10,054
- 10
- 63
- 85
Yes there is a performance hit when using Reflection but a possible workaround for optimization is caching the method:
Method md = null; // Call while looking up the method at each iteration.
millis = System.currentTimeMillis( );
for (idx = 0; idx < CALL_AMOUNT; idx++) {
md = ri.getClass( ).getMethod("getValue", null);
md.invoke(ri, null);
}
System.out.println("Calling method " + CALL_AMOUNT+ " times reflexively with lookup took " + (System.currentTimeMillis( ) - millis) + " millis");
// Call using a cache of the method.
md = ri.getClass( ).getMethod("getValue", null);
millis = System.currentTimeMillis( );
for (idx = 0; idx < CALL_AMOUNT; idx++) {
md.invoke(ri, null);
}
System.out.println("Calling method " + CALL_AMOUNT + " times reflexively with cache took " + (System.currentTimeMillis( ) - millis) + " millis");
will result in:
[java] Calling method 1000000 times reflexively with lookup took 5618 millis
[java] Calling method 1000000 times reflexively with cache took 270 millis

- 8,857
- 3
- 60
- 68
-
Reusing method/constructor is indeed useful and helps, but note that test above does not give meaningful numbers due to the usual benchmarking problems (no warmup, so first loop in particular is mostly measuring JVM/JIT warmup time). – StaxMan Jul 15 '16 at 05:01
Interestingly enough, settting setAccessible(true), which skips the security checks, has a 20% reduction in cost.
Without setAccessible(true)
new A(), 70 ns
A.class.newInstance(), 214 ns
new A(), 84 ns
A.class.newInstance(), 229 ns
With setAccessible(true)
new A(), 69 ns
A.class.newInstance(), 159 ns
new A(), 85 ns
A.class.newInstance(), 171 ns

- 111
- 1
- 2
-
1Seems obvious to me in principle. Do these numbers scale linearly, when running `1000000` invocations? – Lukas Eder Dec 29 '11 at 20:12
-
Actually `setAccessible()` can have much more difference in general, especially for methods with multiple arguments, so it should always be called. – StaxMan Jul 15 '16 at 05:02
Reflection is slow, though object allocation is not as hopeless as other aspects of reflection. Achieving equivalent performance with reflection-based instantiation requires you to write your code so the jit can tell which class is being instantiated. If the identity of the class can't be determined, then the allocation code can't be inlined. Worse, escape analysis fails, and the object can't be stack-allocated. If you're lucky, the JVM's run-time profiling may come to the rescue if this code gets hot, and may determine dynamically which class predominates and may optimize for that one.
Be aware the microbenchmarks in this thread are deeply flawed, so take them with a grain of salt. The least flawed by far is Peter Lawrey's: it does warmup runs to get the methods jitted, and it (consciously) defeats escape analysis to ensure the allocations are actually occurring. Even that one has its problems, though: for example, the tremendous number of array stores can be expected to defeat caches and store buffers, so this will wind up being mostly a memory benchmark if your allocations are very fast. (Kudos to Peter on getting the conclusion right though: that the difference is "150ns" rather than "2.5x". I suspect he does this kind of thing for a living.)

- 938
- 1
- 9
- 15
Yes, it is significantly slower. We were running some code that did that, and while I don't have the metrics available at the moment, the end result was that we had to refactor that code to not use reflection. If you know what the class is, just call the constructor directly.

- 13,693
- 23
- 74
- 128
-
1+1 I've had a similar experience. It's good to make sure to only use reflection if it's absolutely necessary. – Ryan Thames Jan 12 '09 at 20:29
-
In the doReflection() is the overhead because of Class.forName("misc.A") (that would require a class lookup, potentially scanning the class path on the filsystem), rather than the newInstance() called on the class. I am wondering what the stats would look like if the Class.forName("misc.A") is done only once outside the for-loop, it doesn't really have to be done for every invocation of the loop.

- 41
- 1
Yes, always will be slower create an object by reflection because the JVM cannot optimize the code on compilation time. See the Sun/Java Reflection tutorials for more details.
See this simple test:
public class TestSpeed {
public static void main(String[] args) {
long startTime = System.nanoTime();
Object instance = new TestSpeed();
long endTime = System.nanoTime();
System.out.println(endTime - startTime + "ns");
startTime = System.nanoTime();
try {
Object reflectionInstance = Class.forName("TestSpeed").newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
endTime = System.nanoTime();
System.out.println(endTime - startTime + "ns");
}
}

- 188,989
- 46
- 291
- 292

- 777
- 7
- 7
-
4Note that you should separate the lookup (`Class.forName()`) from the instanciation (newInstance()), because they vary significantly in their performance characteristics and you can occasionally avoid the repeated lookup in a well-designed system. – Joachim Sauer Jan 12 '09 at 14:39
-
4Also: you need to execute each task many, many times to get a useful benchmark: first of all the actions are too slow to be measured reliably and secondly you'll need to warm up the HotSpot VM to get useful numbers. – Joachim Sauer Jan 12 '09 at 14:40
Often you can use Apache commons BeanUtils or PropertyUtils which introspection (basically they cache the meta data about the classes so they don't always need to use reflection).

- 8,967
- 18
- 65
- 95
I think it depends on how light/heavy the target method is. if the target method is very light(e.g. getter/setter), It could be 1 ~ 3 times slower. if the target method takes about 1 millisecond or above, then the performance will be very close. here is the test I did with Java 8 and reflectasm :
public class ReflectionTest extends TestCase {
@Test
public void test_perf() {
Profiler.run(3, 100000, 3, "m_01 by refelct", () -> Reflection.on(X.class)._new().invoke("m_01")).printResult();
Profiler.run(3, 100000, 3, "m_01 direct call", () -> new X().m_01()).printResult();
Profiler.run(3, 100000, 3, "m_02 by refelct", () -> Reflection.on(X.class)._new().invoke("m_02")).printResult();
Profiler.run(3, 100000, 3, "m_02 direct call", () -> new X().m_02()).printResult();
Profiler.run(3, 100000, 3, "m_11 by refelct", () -> Reflection.on(X.class)._new().invoke("m_11")).printResult();
Profiler.run(3, 100000, 3, "m_11 direct call", () -> X.m_11()).printResult();
Profiler.run(3, 100000, 3, "m_12 by refelct", () -> Reflection.on(X.class)._new().invoke("m_12")).printResult();
Profiler.run(3, 100000, 3, "m_12 direct call", () -> X.m_12()).printResult();
}
public static class X {
public long m_01() {
return m_11();
}
public long m_02() {
return m_12();
}
public static long m_11() {
long sum = IntStream.range(0, 10).sum();
assertEquals(45, sum);
return sum;
}
public static long m_12() {
long sum = IntStream.range(0, 10000).sum();
assertEquals(49995000, sum);
return sum;
}
}
}
The complete test code is available at GitHub:ReflectionTest.java

- 1
- 14
- 14