问题
I've been working on an instantiation method that will allow me to package a variety of similar classes into one outer class. I could then instantiate each unique class type by passing the name of that type to the constructor. After a lot of research and errors, this is what I have come up with. I have left an error, to demonstrate my question.
import java.lang.reflect.Constructor;
public class NewTest
{
public static void main(String[] args)
{
try
{
Class toRun = Class.forName("NewTest$" + args[0]);
toRun.getConstructor().newInstance();
}
catch(Exception ex)
{
ex.printStackTrace();
System.out.println(ex.getMessage());
}
}
public NewTest(){}
private class one //Does not instantiate
{
public one()
{
System.out.println("Test1");
}
}
private static class two //Instantiates okay
{
public two()
{
System.out.println("Test2");
}
}
}
Compiling this code and running java NewTest two
results in the output Test2
, as I intended.
Running java NewTest one
results in
java.lang.NoSuchMethodException: NewTest$one.<init>()
at java.lang.Class.getConstructor(Unknown Source)
at java.lang.Class.getConstructor(Unknown Source)
at NewTest.main(NewTest.java:12)
I'm confused about this because, as far as I know, I am referencing an inner class correctly, an outer class should have access to an inner class, and I have a default no arg constructor.
回答1:
Non-static inner classes need an instance of the outer class to work properly. So, they don't "really" have a default constructor, they always have a kind of hidden parameter in which they expect an outer class instance.
I don't know why you want to have them all in a single class. If you are doing this so that it's only one file, put them in a package and in separate classes. Having less files does not make your program better.
If instead you need them to share something, so the outer class will work as a kind of "scope", you can still do that without using inner classes, but by passing them a context of some sort.
If you really really want to instantiate the inner class, you need to use the hidden constructor taking the outer class as a parameter :
NewTest outer = new NewTest();
Class<?> toRun = Class.forName("NewTest$" + args[0]);
Constructor<?> ctor = toRun.getDeclaredConstructor(NewTest.class);
ctor.newInstance(outer);
回答2:
A non-static inner class cannot be instantiated without an instance of its parent class.
new NewTest().new one()
The call above will successfully instantiate a one
.
Your two
is being instantiated without an outer instance, because of the static
modifier. It is a static nested class.
See the difference between static nested classes and inner classes: http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
回答3:
You need to make class one
static. Non-static nested classes must be instantiated with an instance of the containing class.
来源:https://stackoverflow.com/questions/25634542/newinstance-with-inner-classes