根据内部类中的类型参数键入声明

时间:2015-06-25 13:56:37

标签: java generics inner-classes

Java阴影类型参数?我发现自己很难测试,因为Java泛型在运行时没有得到确定。

例如,给定此代码:

public class NestedGeneric<T> {
    private InnerGeneric<T> innerGenericInstance;

    private static class InnerGeneric<T> {
        public T innerGenericField;
    }

    NestedGeneric() {
    innerGenericInstance = new InnerGeneric<T>();
    }
}

以下两个语句编译正常:

NestedGeneric<Integer> test1 = new NestedGeneric<Integer>();
NestedGeneric.InnerGeneric<String> test2  = new NestedGeneric.InnerGeneric<String>();

NestedGeneric传递一个类型参数及其构造函数时,T是什么?它是否总是与传递给nestedGeneric的类型参数相同?

换句话说,可以将外部类类型参数传递给内部类泛型类型声明吗?

3 个答案:

答案 0 :(得分:6)

  

换句话说,我想问题是,外部类可以输入   参数是否传递给内部类泛型类型声明?

没有。外部和内部静态类之间没有任何关系(如继承或字段)。您可以创建内部静态类的对象,而不依赖于外部类,如示例所示:

NestedGeneric.InnerGeneric<String> test2  = new NestedGeneric.InnerGeneric<String>();

但是,当您使用内部类的实例作为字段时,泛型类型派生自外部类:

private InnerGeneric<T> innerGenericInstance;

innerGenericInstance = new InnerGeneric<T>();

第三种变体是将内部类定义为字段(非静态)

private class InnerGeneric<T> {
    public T innerGenericField;
}

现在将从外部类中获取类型,因为它是一个成员变量。

正如在定义内部静态和静态的评论中所指出的那样。具有该类型的外部类将使读者(以及稍后的时间点)混淆。它应该用不同的通用声明声明

public class NestedGeneric<T> {
    private InnerGeneric<T> innerGenericInstance;

    private static class InnerGeneric<U> {
        private U innerGenericField;
    }

    NestedGeneric() {
        innerGenericInstance = new InnerGeneric<T>();
    }
}

答案 1 :(得分:5)

这不是影子。代码中只有一个类型参数T参数。因此内部和外部T是相同的类型参数。

您当然可以拥有更多类型参数。

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>();
  } 
}

INNER_TYPEOUTER_TYPE是两种不同的类型参数。行InnerGeneric<OUTER_TYPE> innerGenericInstance = new InnerGeneric<OUTER_TYPE>();会说thad innerGenericInstance的参数化类型与OUTER_TYPE相同。但它们不一定是一样的。就像secondInnerGenerics变量一样。

答案 2 :(得分:4)

是的,但不是静态修饰符:

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();
    }
}