是什么使通用类型参数的名称通用?

时间:2018-12-04 12:45:38

标签: java generics

我正在为自己编写一本Java手册,我希望提供扎实的事实。 我似乎无法描述泛型类型参数。我想知道什么名称显示为编译器的通用类型,而不是现有的对象。我知道约定是字母“ T”和其他单个字母。但是我在oracle.docs.com中看到了一个类似的示例:

class name<T1, T2, ..., Tn>{}

所以现在我很困惑。为了使编译器采用名称作为泛型类型参数,是否仅应存在一个没有该名称的类? 如果我上过Boby课:

class Boby{ ... }

然后,如果我创建一个方法并将类的名称错误键入Bob:

void Method(Bob parameter){}

这只是编译并且参数变成通用类型吗?

3 个答案:

答案 0 :(得分:1)

任何名称都可以是通用类型参数。如果您声明通用类型参数Bob,并使用该名称而不是预期的类名Boby,则编译器会将其识别为通用类型参数。

顺便说一句,如果您声明通用类型参数Boby,它将隐藏类名Boby,因此在定义该通用类型参数的范围内的任何地方写入Boby(在整个类或单个方法中)将引用泛型类型参数,而不是Boby类。

class Something<Bob> {
    void Method1(Bob parameter){} // refers to the generic type parameter Bob

    void Method2(Boby parameter){} // refers to the Boby class
}

class Something<Boby> {
    void Method(Boby parameter){} // refers to the generic type parameter Boby,
                                  // hiding the Boby class
}

class Something<T> {
    void Method(Bob parameter){} // compilation error - Bob is an undefined symbol
}

也就是说,为了使您的代码更具可读性,将单个大写字母用作类型参数名称是一个好习惯。

答案 1 :(得分:0)

在类上声明的type参数会覆盖任何实际的类,就像本地类一样:

interface HasValue {
    int getValue();
}
class Foo {
}

class Bar implements HasValue {
    private int value;

    public Bar(int v) {
        this.value = v;
    }
    public int getValue() {
        return this.value;
    }
}

class Example<Foo extends HasValue> {
    public static final void main(String[] args) throws Exception {
        Example<Bar> e = new Example<>();
        e.method(new Bar(42));
    }

    public void method(Foo x) {
        System.out.println("x.getValue() is " + x.getValue());
    }
}

那很好,因为在Example中,Foo是类型参数,而不是类Foo

答案 2 :(得分:0)

要让编译器知道某个类是否用作通用类,您需要像这样指定它:

public class MyClass<T> {}

例如,如果您为列表创建通用名称,则假定以下内容:

List<Bob> bobyes = new ArrayList<Bob>();

因此,您现在有了一个泛型列表,其中包含Bob类型的class元素。 列表中每个元素的所有类型都是Bob。

如果您进行遍历,您将拥有:

foreach (Bob bob : bobyes)
   if (bob instanceof Bob)
      true; -- in this case always true;