Declare a private static nested class with a public constructor Java?

716 Views Asked by At

How do I create an instance of a static private inner class with a public constructor?

public class outerClass<E> {
private static class innerClass<E> {
    E value;
    
    public innerClass(E e) {
        value = e;
    }
}}

I've tried this and it gives an error that the out package does not exist

outerClass<Integer> out = new outerClass<Integer>();
out.innerClass<Integer> = new out.innerClass<Integer>(1);

I've tried this and it gives an error that the inner class is private and can't be accessed.

outerClass<Integer>.innerClass<Integer> = new 
outerClass<Integer>.innerClass<Integer>(1)
2

There are 2 best solutions below

2
On

new out.innerClass<Integer>(1);

But this doesn't make sense. innerClass is declared static, which means that innerClass has nothing to do with outerClass; it is merely located within it for namespacing purposes (and, perhaps, that outer and inner can access private members), but that is where it ends. So, out, being an instance of outerClass, has no business being there.

new outerClass<Integer>.innerClass<Integer>(1)

That also doesn't make any sense - outerClass is being mentioned here just for the purposes of namespacing: To tell java what class you mean. Thus, the <Integer> on that makes no sense.

how do I do it then?

new outerClass.innerClass<Integer>(1);
1
On

You didn't mention an constraints, so....

Reflection to the rescue!

package com.example;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class ReflectionTest {

    public static class OuterClass<E> {
        private static class InnerClass<E> {
            E value;

            public InnerClass(E e) {
                value = e;
            }
        }
    }

    @Test
    public void should_instantiate_private_static_inner_class_w_reflection()
            throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException,
                   IllegalAccessException, InvocationTargetException, InstantiationException {

        Class<?> innerCls = Class.forName("com.example.ReflectionTest$OuterClass$InnerClass");
        Constructor<?> ctor = innerCls.getConstructor(Object.class);

        Object instance = ctor.newInstance(10);
        Field valueField = innerCls.getDeclaredField("value");
        valueField.setAccessible(true);
        Object value = valueField.get(instance);

        assertEquals(value, 10);
    }
}