问题
Does Java shadow type parameters? I am finding it hard to test for myself because Java generics do not get reified at run time.
For example, given this code:
public class NestedGeneric<T> {
private InnerGeneric<T> innerGenericInstance;
private static class InnerGeneric<T> {
public T innerGenericField;
}
NestedGeneric() {
innerGenericInstance = new InnerGeneric<T>();
}
}
Both the below statements compile fine:
NestedGeneric<Integer> test1 = new NestedGeneric<Integer>();
NestedGeneric.InnerGeneric<String> test2 = new NestedGeneric.InnerGeneric<String>();
When the NestedGeneric
is passed a type parameter and its constructor called, what is T
? Is it always going to be the same as the type parameter passed to nestedGeneric
?
In other words, can an outer classes type parameters be passed to an inner classes generic type declarations?
回答1:
In other words, I suppose the question is, can an outer classes type parameters be passed to an inner classes generic type declarations?
No. There is no relationship (like inheritance or as a field) between the outer and the inner static class. You can create an object of the inner static class without any dependency on the outer class like in your example:
NestedGeneric.InnerGeneric<String> test2 = new NestedGeneric.InnerGeneric<String>();
However when you use an instance of the inner class as a field the generic type is derived from the outer class:
private InnerGeneric<T> innerGenericInstance;
innerGenericInstance = new InnerGeneric<T>();
A third variation would be to define the inner class as a field (non-static):
private class InnerGeneric<T> {
public T innerGenericField;
}
which will now get the type from the outer class since its a member variable.
As pointed out in the comment defining both inner static & outer class with the type will just confuse the reader (and yourself at a later point in time). It should be declared with a different generic like
public class NestedGeneric<T> {
private InnerGeneric<T> innerGenericInstance;
private static class InnerGeneric<U> {
private U innerGenericField;
}
NestedGeneric() {
innerGenericInstance = new InnerGeneric<T>();
}
}
回答2:
This is not a shadowing. There is only one type parameter int your code, the T
parameter. So inner and outer T
are the same type parameters.
You can of course have more type parameters.
public class NestedGeneric<OUTER_TYPE> {
private static class InnerGeneric<INNER_TYPE> {
public INNER_TYPE innerGenericField;
}
public NestedGeneric() {
InnerGeneric<OUTER_TYPE> innerGenericInstance = new InnerGeneric<OUTER_TYPE>();
InnerGeneric<String> secondInnerGenerics = new InnerGeneric<String>();
}
}
The INNER_TYPE
and the OUTER_TYPE
are two different type parameters. Line InnerGeneric<OUTER_TYPE> innerGenericInstance = new InnerGeneric<OUTER_TYPE>();
will say thad innerGenericInstance
is parametrized by the same type as OUTER_TYPE
is. But they do not have to be the same. As it is in the case of secondInnerGenerics
variable.
回答3:
Yes, but not with the static modifier:
public class NestedGeneric<T> {
private InnerGeneric<T> innerGenericInstance;
private class InnerGeneric<T> {
private T innerGenericField;
public InnerGeneric(T innerGenericField){
this.innerGenericField = innerGenericField;
}
public T getInnerGenericField(){
return this.innerGenericField;
}
}
NestedGeneric(T someGenericVariable) {
innerGenericInstance = new InnerGeneric<T>(someGenericVariable);
T innerGenericField = innerGenericInstance.innerGenericInstance();
}
}
来源:https://stackoverflow.com/questions/31052476/type-declaration-based-on-type-parameters-in-inner-classes