为啥我会在这里收到类型安全警告? (泛型)
Posted
技术标签:
【中文标题】为啥我会在这里收到类型安全警告? (泛型)【英文标题】:Why do I get a Type safety warning here? (generics)为什么我会在这里收到类型安全警告? (泛型) 【发布时间】:2011-03-25 13:30:57 【问题描述】:我最近想了解更多有关泛型方法的信息并创建了几个示例,但我不清楚以下类型安全性。举个例子:
public class GeneralMethod
public static void main( String[] args )
Repository rep = new Repository();
Set<ConcreteObject> set = rep.getObject();
abstract class AbstractRepository
public abstract <T extends SuperObject> Set<T> getObject();
class Repository extends AbstractRepository
@Override
public Set<ConcreteObject> getObject() //<- Type safety!
return new HashSet<ConcreteObject>();
abstract class SuperObject
class ConcreteObject extends SuperObject
在 Eclipse 中 Repository.class
出现以下类型安全:
Type safety: The return type Set < ConcreteObject > for getObject() from the type Repository needs checked conversion to conform to Set < SuperObject > from the type AbstractRepository
为什么编译器要符合Set < SuperObject > instead of Set < T extends Superobject >
?
你会如何告诉每个 Repository 用自己的类型实现 getObject()
方法,并且只在方法签名中使用泛型? (意思是没有在类签名中定义泛型)。
谢谢你, 梅内
【问题讨论】:
【参考方案1】:你会如何告诉每个 Repository 用自己的类型实现一个 getObject() 方法,只在方法签名中使用泛型? (意思是没有在类签名中定义泛型)。
你不能。当您说“它是自己的类型”时,您指的是 Repository 子类的泛型类型 - 除非您正在执行类似 FooRepository extends AbstractRepository<Foo>
的操作,否则它不存在。
在这种情况下,我会简单地将抽象类设为泛型:
public abstract class AbstractRepository<T extends SuperObject>
abstract Set<T> getObjects();
顺便说一句,没有非抽象方法的抽象类可能更好地设计为接口。
【讨论】:
Idd,在没有泛型类的情况下尝试它的原因是,真正的抽象类已经有两个泛型,所以我不会为单个方法添加第三个,因为它可能会混淆更多比它有帮助。也许我只需要重新考虑该方法的当前类设计。谢谢!【参考方案2】:class AbstractRepository
Set<? extends SuperObject> getObject();
class Repository extends AbstractRepository
Set< ConcreteObject > getObject()
这是因为Set<ConcreteObject>
是Set<? extends SuperObject>
的子类型
另见Overriding method with generic return type
【讨论】:
对不起,我的回复晚了,但谢谢。这正是我想要的!【参考方案3】:AbstractRepository repository = new Repository();
Set<SuperObject> set = repository.getObject();
这应该可以编译,但您会将Set<ConcreteObject>
分配给Set<SuperObject>
变量。
返回Set<? extends SuperObject>
应该编译[未测试]。您可能希望使基类通用(或根本不返回集合)。
【讨论】:
示例已经编译。我只是不太清楚,为什么会有警告。 Idd 更好的解决方案可能是使基类通用。只是想避免它,因为原始基类已经有两个泛型。 编译,我的意思是编译没有警告。【参考方案4】:“为什么编译器要符合Set
因为你是这么告诉他的! 毕竟,可以替代 T 的最少类型是 Superobject。
【讨论】:
哦,好的,我不太清楚,谢谢。我以为这样我会告诉编译器我明确想要一个扩展 SuperObject 的类。【参考方案5】:T extends SuperObject
将T
绑定到extends
(是SuperObject
的子类)的任何类。您正在覆盖 AbstractRepository.getObject()
方法,因此方法签名必须与其父类相同。
这应该是有效的(未经测试)
class Repository extends AbstractRepository
@Override
public Set<T extends SuperObject> getObject() //Valid
return new HashSet<ConcreteObject>();
【讨论】:
不幸的是它无效,因为你不能在方法返回类型中使用'T extends xxx'。但感谢您的努力。 @ymene,不幸的是,您的代码就是这样设置的。如果你想知道具体的返回类型,你可以让你的类通用。以上是关于为啥我会在这里收到类型安全警告? (泛型)的主要内容,如果未能解决你的问题,请参考以下文章
为啥我会收到来自 FxCop 的 InitializeReferenceTypeStaticFieldsInline 警告?
为啥我会收到 JDBC 驱动程序警告和 ThreadLocal 错误?
为啥我会收到带有 std::bind() 的“本地临时返回地址”警告?
为啥在 C# 10 中我会在初始化属性上收到编译器警告/错误 CS8618
为啥我会收到警告:当 mysql-python 安装成功时,找不到与“MANIFEST”、“ChangeLog”、“GPL”匹配的文件