7

So I have something like the following:

public class Enclosing<T extends Comparable<T>> {
    // non-relevant code snipped
    public class Inner {
        private T value;
        public Inner(T t) {
            value = t;
        }
    }
}

Everything compiles and the world is happy. However, whenever I try to create an instance of Enclosing.Inner as follows, I can't:

new Enclosing<Integer>.Inner(5);

The following error happens:

Cannot allocate the member type Enclosing<Integer>.Inner using a parameterized compound name; use its simple name and an enclosing instance of type Enclosing<Integer>.

It is important to note that I cannot make the inner class static, because it contains a field of type T.

How can I work around this?

knpwrs
  • 15,691
  • 12
  • 62
  • 103
  • 1
    Re: "It is important to note that I cannot make the inner class `static`, because it contains a field of type `T`": That sounds more like a reason to make the inner class generic, using the same bounds as the outer class, than like a reason to make the inner class non-static. (Not to say your inner class *should* be static, though. That depends on your design as a whole, not this one detail.) – ruakh Nov 22 '11 at 02:14

2 Answers2

14

To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:

  Enclosing<Integer> outerObject = new Enclosing<Integer>();
  Enclosing<Integer>.Inner innerObject = outerObject.new Inner();

The ugly syntax suggests a code smell in this design. There should probably be a factory method of some kind in the Enclosing class (getInner or something) and the inner class should probably implement a public interface if it is being used from outside its enclosing class.

Thilo
  • 257,207
  • 101
  • 511
  • 656
0

just ran into the same problem, solved it the following way in java7

public class Test {
    static class A<T> {
        public class B {

        }
    }
    A<String> a = new A();
    class C extends A.B {
        C() {
            Test.this.a.super();
        }
    }
    public void test() {
        C c = new C();
        A.B b = this.a.new B();
    }
}
aepurniet
  • 1,719
  • 16
  • 24