我正在为自己编写一本Java手册,我希望提供扎实的事实。 我似乎无法描述泛型类型参数。我想知道什么名称显示为编译器的通用类型,而不是现有的对象。我知道约定是字母“ T”和其他单个字母。但是我在oracle.docs.com中看到了一个类似的示例:
class name<T1, T2, ..., Tn>{}
所以现在我很困惑。为了使编译器采用名称作为泛型类型参数,是否仅应存在一个没有该名称的类? 如果我上过Boby课:
class Boby{ ... }
然后,如果我创建一个方法并将类的名称错误键入Bob:
void Method(Bob parameter){}
这只是编译并且参数变成通用类型吗?
答案 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;