Java Generators with Inner Class and Inner Interface

Below I have a generic OuterClass, an InnerClass that uses OuterClass generators and a non-generic InnerInterface.

public class OuterClass<E> { public class InnerClass { public E someMethod() { return null; } } public interface InnerInterface{ public void onEvent(OuterClass.InnerClass innerClass); } } 

In the main method below, I use two instances of OuterClass, o1 with parameters and with o2 s. My anonymous inner class myListener is trying to use the generic type of the outer class (E). The code, as it is below, does not compile (Integer i = innerClass.someMethod () - Type mismatch: cannot be converted from Object to Integer).

 public class Test { public static void main(String[] args) { OuterClass<Integer> o1 = new OuterClass<Integer>(); OuterClass<String> o2 = new OuterClass<String>(); OuterClass.InnerInterface innerInterface = new OuterClass.InnerInterface() { @Override public void onEvent(InnerClass innerClass) { Integer i = innerClass.someMethod(); } }; } } 

I would like to express that myListener is for o1, and should use E = Integer without repeating it (without repeating, I already say this when declaring o1). Is it possible?

Many thanks! Faton.

+9
java generics
source share
2 answers

The internal interface or enumeration is implicitly static, and static members are not parameterized by parameters of the type of the outer class. Therefore, InnerInterface should look like this:

 public interface InnerInterface<E> { void onEvent(OuterClass<E>.InnerClass innerClass); } 

Note that the E InnerInterface parameter InnerInterface not match the E OuterClass parameter.

+14
source share

As always, nested non- private types do not help keep things simple. Pull out the boat and create new files, even if your IDe is working against you.

In any case, the static members of the class do not share the general parameters of the outer class. This is important for field behavior and provides great flexibility for static nested types (like InnerInterface ), even if you don't want to. Thus, in your case, you need to provide your (static) nested interface with a common parameter. For $ deity, use a different identifier!

 public class OuterClass<E> { public class InnerClass { public E someMethod() { return null; } } public interface InnerInterface<T> { void onEvent(OuterClass<T>.InnerClass innerClass); } } public class Test { public static void main(String[] args) { OuterClass<Integer> o1 = new OuterClass<Integer>(); OuterClass<String> o2 = new OuterClass<String>(); OuterClass.InnerInterface<Integer> innerInterface = new OuterClass.InnerInterface<Integer>() { @Override public void onEvent(OuterClass<Integer>.InnerClass innerClass) { Integer i = innerClass.someMethod(); } }; } } 

(I also qualified InnerClass , if necessary.)

Edit: maybe you should just take a look at the original anonymous inner class in isolation from the rest of the use:

 public interface InnerInterface{ public void onEvent(OuterClass.InnerClass innerClass); } OuterClass.InnerInterface innerInterface = new OuterClass.InnerInterface() { @Override public void onEvent(InnerClass innerClass) { Integer i = innerClass.someMethod(); } }; 

Integer appears only once, in a place where it clearly cannot be considered correct.

+1
source share

All Articles