I was getting a java.lang.InstantiationException when I tried to call clazz.newInstance() to reflectively instantiate some classes.
Here are the steps I tried as I worked to understand what was happening:
- The newInstance() call was being performed in a method in the production code. I thought maybe there was something odd about how I was passing a
Class<? extends TransactionManagerLookup>object into that method under test, so I tried performing the reflective instantiation call locally, in my test method:
Same error as before.
- Next, I tried instantiating my class directly, with
That worked. Ok…
- The thing I was trying to reflectively instantiate was of type
Class<? extends TransactionManagerLookup>. I thought maybe the TransactionManagerLookup interface was somehow gumming up the reflective instantiation, so I created an empty class called PlainClass, which did not implement TransactionManagerLookup, and tried
Same error, while again, new PlainClass() worked fine.
- My next question was, can I use newInstance() to successfully instantiate anything? I tried
and did not get the error.
- At this point I was confused and asked Ben if he would take a look at it. In the process of explaining my woes, one of us — I don’t remember if it was Ben or me — noticed that PlainClass and PlainLookup, which are inner classes of my test class, were not static inner classes.
Adding static to the class definitions fixed the issue! There’s theory behind that, but for now I’ll just quote Joshua Bloch on the matter: “Favor static member classes over nonstatic” (Item 22 in Effective Java (2nd ed.)). I had forgotten…