我该怎么做这个java通用演员?
public interface IField {
}
class Field implements IField { // package private class
}
public class Form {
private List<Field> fields;
public List<IField> getFields() {
return this.fields;
}
}
Run Code Online (Sandbox Code Playgroud)
return语句会抛出一个编译错误(我知道原因 - 我读过泛型教程),但编写这样的代码会非常方便.
如果我将"fields"声明为List,则需要在Form类的其他方法中对Field使用大量的强制转换.
我可以强制该死的编译器弯曲它的规则并编译返回语句吗?
提前致谢.
Jon*_*eet 17
更好的解决方案IMO是更改方法的签名以使用有界通配符:
public List<? extends IField> getFields()
Run Code Online (Sandbox Code Playgroud)
这将让调用者将列表中的任何内容视为IField,但它不会让调用者在列表中添加任何内容(没有强制转换或警告),因为他们不知道"真实"类型是什么列表是.
小智 12
碰巧,你可以,因为Java泛型只是嫁接,而不是类型系统的一部分.
你可以做
return (List<IField>)(Object)this.fields;
Run Code Online (Sandbox Code Playgroud)
因为所有List<T>对象都是相同的底层类型.
请记住,这允许任何人IField在列表中放置任何类型的实现,因此如果您的集合不是只读的,则可能会遇到困难.
不要这样做.
A List<Field>不是List<IField>.您可以尝试强制编译器接受(我认为这是不可能的,我希望它不可能),但这会让您陷入困境.编译器将允许用户将从IField派生的AnotherField引入到给定的List中,从而破坏不变量,并打破泛型提供的类型安全性.稍后使用List<Field>will会因为奇怪元素的提取而无法将隐式强制转换为Field,而您不会期望它发生.
如果你确实需要返回a List<IField>而不是List<Field>,那么我建议生成一个填充了相同元素的新列表.如果您可以修改您的界面,请转到Jon Skeets解决方案.
| 归档时间: |
|
| 查看次数: |
16206 次 |
| 最近记录: |