Type declaration based on type parameters in inner classes

▼魔方 西西 提交于 2021-01-27 02:22:09

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!