什么是?
。是否与 Java 编译器的实现细节有关或类型在 JLS 中定义? .
例如,
public interface RecipientTypeVisitor<ReturnType> {
public ReturnType visit(RecipientSetType t);
}
public class RecipientSetType extends RecipientType{
public Integer accept(RecipientTypeVisitor<?> visitor){ //Error:
return visitor.visit(this); //Cannot convert capture of #1 to Integer
}
}
但是如果我们这样写:
public interface RecipientTypeVisitor<ReturnType> {
public ReturnType visit(RecipientSetType t);
}
public class RecipientSetType extends RecipientType{
public Object accept(RecipientTypeVisitor<?> visitor){ //Ok:
return visitor.visit(this); //this implies tha the capture of #1 is
//a subtype of Object as any refrence type in Java.
}
}
关于捕获的类型
,我只能说这些了。那么它到底是什么?
最佳答案
捕获的通配符类型是编译器使用的一种类型,在一个特定的地方表示通配符类型的特定实例的类型。
示例:以一个带有两个通配符参数的方法为例,void m(Ex<?> e1, Ex<?> e2)
. e1
的声明类型和 e2
写得一模一样,Ex<?>
.但是e1
和 e2
可能具有不同且不兼容的运行时类型。
类型检查器不能认为类型相等,即使它们以相同的方式编写。因此,在编译期间 e1
的类型参数和 e2
被赋予特定的类型,每个地方都有新的类型。这些新类型称为对其声明类型的捕获。
通配符的捕获是未知的,但正常且具体的类型。它可以像其他类型一样使用。
可以在 JLS 中找到对此的技术说明。 :
5.1.10. Capture Conversion
Let G name a generic type declaration (§8.1.2, §9.1.2) with n type parameters A1,...,An with corresponding bounds U1,...,Un.
There exists a capture conversion from a parameterized type G (§4.5) to a parameterized type G, where, for 1 ≤ i ≤ n :
- If Ti is a wildcard type argument (§4.5.1) of the form ?, then Si is a fresh type variable whose upper bound is Ui[A1:=S1,...,An:=Sn] and whose lower bound is the null type (§4.1).
- ...
我们可以将其应用于您的示例:
public Integer accept(RecipientTypeVisitor<?> visitor){ //Error:
return visitor.visit(this); //Cannot convert capture of #1 to Integer
}
捕获 RecipientTypeVisitor
的类型参数在编译期间引入。捕获的类型参数是具体的但完全未知(JLS 称其为“新类型变量”),当然不能转换为 Integer
.
没有办法直接表示对通配符类型的捕获,因此您不能声明该类型的变量或对其做很多事情。但是,您可以通过以它作为参数调用泛型方法来间接为其命名。我引用的 JLS 部分有一个很好的例子:
public static void reverse(List<?> list) { rev(list); } private static <T> void rev(List<T> list) { List<T> tmp = new ArrayList<T>(list); for (int i = 0; i < list.size(); i++) { list.set(i, tmp.get(list.size() - i - 1)); } }
关于java - 了解 Java 中的捕获类型(符号 '?'),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30797805/