Below I have a generic OuterClass, an InnerClass that use OuterClass generics and 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 instance of OuterClass, o1 parameterized with , and o2 with . My annonymous inner class myListener tries 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 convert 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 it when declaring o1). Is that possible?
Many thanks! Faton.
Generic Interfaces in Java are the interfaces that deal with abstract data types. Interface help in the independent manipulation of java collections from representation details. They are used to achieving multiple inheritance in java forming hierarchies. They differ from the java class.
Generics means parameterized types. The idea is to allow type (Integer, String, … etc., and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types.
A class that is defined within another class is called a nested class. An inner class, on the other hand, is a non-static type, a particular specimen of a nested class.
In Java, it is possible to define a class within another class, such classes are known as nested classes. They enable you to logically group classes that are only used in one place, thus this increases the use of encapsulation, and creates more readable and maintainable code.
An inner interface or enum is implicitely static, and static members are not parameterized with the type parameters of the outer class. So InnerInterface
should look like this:
public interface InnerInterface<E> {
void onEvent(OuterClass<E>.InnerClass innerClass);
}
Note that the E
parameter of InnerInterface
is not the same as the E
parameter of OuterClass
.
As always, non-private
nested types don't help keeping things simple. Push the boat out and create some new files, even if your IDe works against you.
Anyway, static members of a class do not share the generic parameters of the outer class. This is important for the behaviour of fields, and allows more flexibility on static nested types (such as InnerInterface
) even if you don't want it. So, in your case, you need to give your (static) nested interface a generic parameter. For $deity's sake, 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've also qualified InnerClass
where necessary.)
Edit: It's probably worth just looking 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
only appears once, in a place where it clearly cannot be inferred to be correct.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With