Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

newInstance() with inner classes

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.

like image 748
Jonathon Anderson Avatar asked Sep 03 '14 00:09

Jonathon Anderson


People also ask

What does class newInstance () do?

Class. newInstance() throws any exception thrown by the constructor, regardless of whether it is checked or unchecked. Constructor. newInstance() always wraps the thrown exception with an InvocationTargetException .

How do I access static nested classes?

And like static class methods, a static nested class cannot refer directly to instance variables or methods defined in its enclosing class: it can use them only through an object reference. They are accessed using the enclosing class name. To instantiate an inner class, you must first instantiate the outer class.

Can outer class access inner class variables?

If the inner class defined as private and protected, can outer class access the members of inner class? Yes.

Can Java inner class be static?

As with instance methods and variables, an inner class is associated with an instance of its enclosing class and has direct access to that object's methods and fields. Also, because an inner class is associated with an instance, it cannot define any static members itself.


2 Answers

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);
like image 104
Simone Gianni Avatar answered Sep 28 '22 07:09

Simone Gianni


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

like image 29
The111 Avatar answered Sep 28 '22 06:09

The111