如何进行java泛型转换?

如何进行java泛型转换?,java,Java,如何进行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; } } 公共接口IField{

如何进行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;

  }

}
公共接口IField{
}
类字段实现IField{//包私有类
}
公开课表格{
私有列表字段;
公共列表getFields(){
返回此字段;
}
}
return语句抛出一个编译器错误(我知道原因——我读了泛型教程),但是编写这样的代码非常方便

若我将“fields”声明为List,那个么我需要在表单类的其他方法中对Field使用大量强制转换

我能强迫那个该死的编译器改变它的规则并编译返回语句吗


提前感谢。

您可以,因为Java泛型只是移植到类型系统上,而不是类型系统的一部分

你能行

return (List<IField>)(Object)this.fields;
返回(列表)(对象)this.fields;
因为所有
List
对象都是相同的基础类型


请记住,这允许任何人在您的列表中放置任何实现
IField
的类型,因此如果您的集合不是只读的,您可能会遇到困难。

Sunlight是正确的,您可以将其强制转换

另一个解决方法是仔细检查是否确实需要
列表
,或者是否可以将内部
字段
变量更改为
列表


只要您只在
IField
界面上的列表内容上使用方法,您就应该能够进行strightforward交换。

更好的解决方案是,IMO,将方法的签名更改为使用有界通配符:

public List<? extends IField> getFields()
public List不要这样做

列表
不是
列表
。您可以尝试强制编译器接受(我认为这是不可能的,我希望这是不可能的),但这会给您带来麻烦。编译器将允许用户在给定列表中引入从IField派生的另一个字段,打破不变量,并打破泛型提供的类型安全性。稍后使用
列表
将中断,因为提取奇怪元素将使隐式强制转换到字段失败,而您不希望发生这种情况


如果您确实需要返回一个
列表
,而不是
列表
,那么我建议您生成一个包含相同元素的新列表。如果可以修改界面,请选择解决方案。

如果调用者不需要修改列表:

return Collections.<IField>unmodifiableList(this.fields);
返回集合.不可修改列表(此.fields);

作为旁注,this.fields被键入为this.fiedls,我没有足够高的代表来编辑其他人的帖子。这种方法的缺点是它会迫使调用者处理通配符。作为一般原则,我建议(IIRC泛型作者也建议)只在方法参数上使用通配符,在返回类型上避免使用通配符。这取决于用例,IMO。如果想法是这实际上只是一个可读取的集合,那么通配符是有意义的(并且准确地表示可用的内容)。如果它也应该是可写的,那么它显然不起作用——事实上也不应该。你能看看这个问题吗?