扩展方法返回类型的Java泛型
看看这三门课。 Minatchi允许自己进行扩展,以便其方法的返回类型也可以扩展。为了说明这一点,我使用了静态方法扩展方法返回类型的Java泛型,java,generics,methods,return-type,Java,Generics,Methods,Return Type,看看这三门课。 Minatchi允许自己进行扩展,以便其方法的返回类型也可以扩展。为了说明这一点,我使用了静态方法 public class Minatchi<T extends Minatchi<?>>{ static public <T extends Minatchi<?>> List<T> listAll(){ return (List<T>) query(); } }
public class Minatchi<T extends Minatchi<?>>{
static public <T extends Minatchi<?>>
List<T> listAll(){
return
(List<T>) query();
}
}
公共类Minatchi>
List listAll(){
返回
(列表)查询();
}
}
所以我把米纳奇归类为女士
public class Lady
extends Minatchi<Lady>{
}
public-class-Lady
米纳奇酒店{
}
这就是可疑行为发生的地方
public class HelloMinatchi{
private void listA(){
List<Lady> uvs = Lady.listAll();
for (Lady uv: uvs){
logger.info(uv.getName() );
}
}
private void listB(){
for (Lady uv: Lady.listAll()){
logger.info(uv.getName() );
}
}
}
公共类HelloMinatchi{
私有无效列表a(){
List uvs=Lady.listAll();
适用于(女士uv:uv){
logger.info(uv.getName());
}
}
私有无效列表b(){
for(Lady uv:Lady.listAll()){
logger.info(uv.getName());
}
}
}
方法listA和listB本质上是相同的。
listA将列表放入中间变量uvs中,
而listB直接将listAll放入for循环头中
然而,对于listB,编译器抱怨无法将Minatchi转换为Lady
所以这个问题是关于Java泛型的设计完整性的。还有一种仿制药抱怨
这是一个故意的设计特性还是Java泛型设计人员不知道如何解决的无意设计缺陷。如果是故意的,他们为什么这样做?如果是bug,他们是否计划解决它
或者这是我个人的问题,我不知道更好的方法来声明泛型?如果是,告诉我怎么做
(我使用了一个泛型Minatchi类,因为我也有非静态方法要暴露于类扩展,我在问题中忽略了这一点。)您的问题是让编译器推断listAll方法的泛型参数,在第一种情况下,它推断出您想要的参数,因为您将结果存储在一个变量中,它可以只查看变量的类型。在第二种情况下,它无法自动推断“正确”类型,因此您需要自己指定:
for (Lady uv: Lady.<Lady>listAll()){
logger.info(uv.getName() );
}
for(Lady-uv:Lady.listAll()){
logger.info(uv.getName());
}
请注意,在这个示例中,Minatchi类没有理由是泛型的,因为它根本不会影响静态方法
还请注意,调用Lady.listAll与调用minachi.listAll完全相同(即,它不影响编译器可以或将推断为泛型参数的类型)。静态方法不从类中获取泛型类型定义。i、 e.
listAll()
方法不知道Lady
(在中)
其返回类型由表达式的左侧推断:
- 在
listA()
中,左侧定义了它需要List
- 在
listB()
中,forEach循环看起来也应该是一个Lady
,但编译器似乎没有正确指示forEach循环
使listB()
工作的方法是告诉它要使用的泛型类型:
for (Lady uv : Lady.<Lady>listAll()) {..}
for(Lady-uv:Lady.listAll()){..}
不幸的是,正如我在另一个问题中提到的:,Java中的隐式类型推断只在赋值中起作用
我还是不知道原因。不过,这对我来说仍然很愚蠢。这是因为类型擦除
从
在实例化泛型类型时,
编译器通过
一种称为类型擦除的技术-a
编译器删除所有
与类型参数相关的信息
和类或类中的类型参数
方法
因为调用Lady.ListAll是在原始类型Minatchi上执行的,所以编译器无法知道特定类型是Minatchi
泛型使用类型擦除,以便泛型类型与泛型添加到库之前编译的Java库兼容。已经做了一些努力,但它不在Java7的路线图上。Lady.listAll(),而不是Lady.listAll();)(为您更正)如果编译器可以从变量推断,那么从for循环头中的变量推断类型肯定不会有问题。对于(Lady uv:Lady.listAll()),这个问题不是关于是否应该使用中间变量。相反,这是关于为什么语言设计者忘记了适应for循环?为什么他们没有/不能使用for循环变量?瞧,他们在抽什么?谢谢。我应该在发布前测试一下。真的吗?我认为类型擦除只发生在运行时。此错误发生在编译时。@nanda:类型擦除发生在编译时-如果在运行时知道类型,则不需要擦除它。我的意思是,是的擦除发生在编译时,因此运行时不知道泛型类型,但在编译类之前会进行错误检查。如果它有错误怎么能编译呢?谢谢bozho。我抽的是什么?我使用了一个通用的Minatchi类,因为我也有非静态的方法暴露于类扩展中,我在问题中忽略了这一点。