理解Java中捕获的类型(symbol';?';)
什么是理解Java中捕获的类型(symbol';?';),java,generics,Java,Generics,什么是?。它是否与Java编译器的实现细节有关,或者类型是在中定义的 比如说, public interface RecipientTypeVisitor<ReturnType> { public ReturnType visit(RecipientSetType t); } public class RecipientSetType extends RecipientType{ public Integer accept(RecipientTypeVisitor
?
。它是否与Java编译器的实现细节有关,或者类型是在中定义的
比如说,
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
}
}
公共接口RecipientTypeVisitor{
公众返回型访问(接受者t型);
}
公共类RecipientSetType扩展了RecipientType{
公共整数接受(RecipientTypeVisitor){//错误:
return visitor.visit(this);//无法将#1的捕获转换为整数
}
}
但如果我们写这篇文章:
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.
}
}
公共接口RecipientTypeVisitor{
公众返回型访问(接受者t型);
}
公共类RecipientSetType扩展了RecipientType{
公共对象接受(RecipientTypeVisitor){//Ok:
回访者。访问(此);//这意味着捕获#1是
//对象的子类型,如Java中的任何引用类型。
}
}
关于
捕获类型
,我只能说这些了。那么它到底是什么呢 每个类都从Object扩展,因此从?
到Object的类型转换是安全的。
要获得与Integer
相同的结果,您可以使用RecipientTypeVisitor您有一些选择:
你必须更换吗?接受方法签名中的整数
您也可以将您的方法参数化:
public不接受(RecipientTypeVisitor){…}
这表示您的方法使用了一些泛型并链接了它的一些组件。通配符类型的捕获是编译器使用的一种类型,它在一个特定位置表示通配符类型的特定实例的类型
示例:以具有两个通配符参数的方法为例,void m(exe1,exe2)
。e1
和e2
的声明类型完全相同,Ex
。但是e1
和e2
可能具有不同且不兼容的运行时类型
类型检查器即使以相同的方式编写也不能考虑类型相同。因此,在编译过程中,
e1
和e2
的类型参数被赋予了特定的类型,每个地方都使用了新的类型。这些新类型称为其声明类型的捕获
通配符的捕获是一种未知的、正常的、具体的类型。它的使用方法与其他类型相同
有关这方面的技术说明,请参见:
5.1.10。捕获转换
让G命名一个泛型类型声明(§8.1.2,§9.1.2),其中包含n个类型参数A1,…,An以及相应的边界U1,…,Un
存在从参数化类型G(§4.5)到参数化类型G的捕获转换,其中,对于1≤ 我≤ n:
- 如果Ti是形式为?的通配符类型参数(§4.5.1),则Si是一个新类型变量,其上限为Ui[A1:=S1,…,An:=Sn],下限为null类型(§4.1)
我们可以将此应用于您的示例:
public Integer accept(RecipientTypeVisitor<?> visitor){ //Error:
return visitor.visit(this); //Cannot convert capture of #1 to Integer
}
字符?
是一个通配符,表示您不知道类型。its并不意味着它的类型是对象
its的定义未定义
,但在Java中,您可以在对象
类型中保存任何类型的对象
ArrayList<?> list1 = new Arraylist<?>(); // list of undefined objects
ArrayList list1=new ArrayList();//未定义对象列表
不能在列表1中添加对象,但在强制转换后可以
ArrayList<Object> list2 = new Arraylist<Object>(); // list of objects of type Object
ArrayList list2=新建ArrayList();//对象类型的对象列表
您可以在列表2中添加任何类型的对象(这是我的另一个答案,但它更适合这个问题,解释通配符本身)
通配符?
不是类型。这是一个类型参数。虽然语法很有欺骗性(故意)
让我们使用不同的语法-如果有任何第一级通配符,请使用{}
而不是
,例如
List{?}, Map{String, ? extends Number}
{?}
的意思是声明联合类型
List{? extends Number} == union of List<Number>, List<Integer>, List<Long>, ....
对于通配符,这是不可能做到的-它没有任何意义
interface List<?>
? get(int)
即使编译时不知道x
的确切类型,我们仍然可以进行替换
interface List<x>
x get(int)
接口列表
x获取(int)
所以我们可以理解调用obj.get(0)
;它返回x
,并且x
是对象的子类型;因此,我们可以将返回值分配给对象
,您想知道有关此对象的确切信息吗?好像是班名?或者别的什么?你想知道为什么你的第一个例子没有编译吗visitor.visit()
返回一个ReturnType
,它不能作为整数返回,而是作为对象返回。在RecipientTypeVisitor中,“?”是一个通配符,您不知道它的类型。如何假定它的整数?所以对于它的编译器来说Object@Aakash我想知道我到底问了些什么。是JLS中定义的类型(及其属性),或者只是实现的内部构件。它可以是ReturnType
或它的子类之一。上面的示例也可以在Maurice Naftalin&Philip Wadler的《Java泛型和集合通配符捕获》一书中找到。类型变量T已捕获通配符
interface List<?>
? get(int)
obj is a List{?} => obj is a List<x>, where x a subtype of Object.
interface List<x>
x get(int)