-2

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)
fdermishin
  • 3,519
  • 3
  • 24
  • 45
user2208569
  • 109
  • 1
  • 11
  • `new innerClass<...>(...)` from inside `outerClass`. From outside `outerClass` it's inaccessible because you declared it private. – khelwood Dec 04 '20 at 22:03
  • `static` means it behaves as as if it were declared at top level (i.e. does not hold a reference to the syntactically enclosing class. `private` means it cannot be seen outside its enclosing class, so there's no point in `new outerClass.innerClass` because where the name `innerClass` is in scope it won't need to be qualified. – Jim Garrison Dec 04 '20 at 22:07
  • So essentially, I cannot declare inner class unless I am writing code from inside outerclass? Any code I write from a separate program that calls this will be unable to instantiate the inner class because it is private? – user2208569 Dec 04 '20 at 22:11
  • That's what private means: only accessible inside the containing class. – khelwood Dec 04 '20 at 22:13

2 Answers2

0

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);
rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • It's saying innerClass has private access in outerClass, and won't let me compile – user2208569 Dec 04 '20 at 22:18
  • 1
    Yes, your class is private. Only code within the `outerClass.java` file can call it. That's... what `private` means. That's like going: "Okay, I have made a circle shape, but, now... how do I put corners on this thing?". – rzwitserloot Dec 04 '20 at 22:31
0

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);
    }
}
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • @thatotherguy Except that it won’t work in Java 9 and later when modules are in use. – VGR Dec 04 '20 at 23:30