返回集合< ChildType>从指定它返回Collection< ParentType> [英] Returning a Collection<ChildType> from a method that specifies that it returns Collection<ParentType>

查看:99
本文介绍了返回集合< ChildType>从指定它返回Collection< ParentType>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想写一个方法来返回一个集合(例如Arraylist),该集合使用泛型作为包含父类或扩展父类的类来声明。对于此方法,集合中的对象将始终用作父类的实例,但在其他上下文中,它们使用不同,因此它们分别保存。例如:

  import java.util.ArrayList; 
import java.util.Collection;

public class TestClass {

public static int PARENTTYPE = 0;
public static int CHILDTYPE = 1;

Collection< ParentClass> parentHolder = new ArrayList< ParentClass>();
Collection< ChildClass> childHolder = new ArrayList< ChildClass>();

public TestClass(){

}

public Collection< ParentClass> getHolder(int type){
if(type == PARENTTYPE){
return parentHolder;
} else if(type == CHILDTYPE){
return childHolder; //< - 不兼容的类型
} else {
throw new RuntimeException(Not an valid type);
}
}

public static void main(String args []){
TestClass test = new TestClass();

Collection< ParentClass> col1 = test.getHolder(PARENTTYPE);
Collection< ParentClass> col2 = test.getHolder(CHILDTYPE);
}
}


  public class ParentClass {
}


$ b b


  public class ChildClass extends ParentClass {
}

但是我在指定的行上收到不兼容的类型异常。如何编写方法,使我可以返回声明为包含扩展某个类的对象的集合。

解决方案

错误原因

引发异常的原因是因为 Collection< ParentClass> 可以具有 ParentClass 已添加到。例如,可以向其中添加以下类的实例

  public class OtherChildClass extends ParentClass {
}

但是因为real集合是 Collection< ChildClass> 这将引发一个错误。或者即使你添加了 ParentClass ,它也会引发一个错误。

解决方案

这可以通过使用 Collection< ;?在类型声明中扩展ParentClass> 。这意味着你返回一个 Collection ,声明为包含一些可以转换为 ParentClass 并称为逆变。此类集合不能向其添加新对象(允许的异常为null),因为编译器无法保证您尝试插入的对象是有效的。但它可以保证从它出来的任何东西可以转换到ParentClass和使用。有关详情,请参阅此处了解详情。使用示例如下:

  import java.util.ArrayList; 
import java.util.Collection;

public class TestClass {

public static int PARENTTYPE = 0;
public static int CHILDTYPE = 1;

ArrayList< ParentClass> parentHolder = new ArrayList< ParentClass>();
ArrayList< ChildClass> childHolder = new ArrayList< ChildClass>();

public TestClass(){
parentHolder.add(new ParentClass());
childHolder.add(new ChildClass());
}

public ArrayList< ;? extends ParentClass> getHolder(int type){
if(type == PARENTTYPE){
return parentHolder;
} else if(type == CHILDTYPE){
return childHolder; //< - 不再不兼容的类型
} else {
throw new RuntimeException(Not an valid type);
}
}

public static void main(String args []){
TestClass test = new TestClass();

ArrayList< ;? extends ParentClass> col1 = test.getHolder(PARENTTYPE);
ArrayList< ;? extends ParentClass> col2 = test.getHolder(CHILDTYPE);

ParentClass childCastToParent = col2.get(0);

}
}



<数组列表已被用于简洁,但同样适用于所有集合


I'm trying to write a method that will return a collection (eg Arraylist) that is declared using generics as containing either a parent class or a class that extends the parent class. For this method the objects in the collection will always be used as instances of the parent class but in other contexts they are used differently hence them being held separately. For example:

import java.util.ArrayList;
import java.util.Collection;

public class TestClass {

    public static int PARENTTYPE=0;
    public static int CHILDTYPE=1;

    Collection<ParentClass> parentHolder=new ArrayList<ParentClass>();
    Collection<ChildClass> childHolder=new ArrayList<ChildClass>();

    public TestClass(){

    }

    public Collection<ParentClass> getHolder(int type){
        if (type==PARENTTYPE){
            return parentHolder;
        }else if (type==CHILDTYPE){
            return childHolder; //<--incompatible types
        }else{
            throw new RuntimeException("Not a valid type");
        }
    }

    public static void main(String args[]){
        TestClass test=new TestClass();

        Collection<ParentClass> col1=test.getHolder(PARENTTYPE);
        Collection<ParentClass> col2=test.getHolder(CHILDTYPE);
    }
}


public class ParentClass {
}


public class ChildClass extends ParentClass{
}

However I receive an incompatible types exception at the indicated line. How can I write the method such that I can return collections declared as containing any objects that extend a certain class.

解决方案

Reason for the error
The reason the exception is raised is because Collection<ParentClass> can have any object that extends ParentClass added to it. For example an instance of the following class could be added to it

public class OtherChildClass extends ParentClass{
}

But because the "real" collection is a Collection<ChildClass> this would raise an error. Or even if you added a ParentClass to it it would raise an error. All in all not good.

Solution
This can be solved however by using Collection<? extends ParentClass> in your type declaration. The meaning of this is that you are returning a Collection that is declared as containing some class that could be cast to ParentClass and is called contravariance. Such a collection cannot have new objects added to it (with the admitted exception of null) because the compiler could never guarantee that what you are trying to put into it is valid. But it can guarantee that whatever comes out of it can be cast to ParentClass and used as such. See here for more details. A usage example is as follows:

import java.util.ArrayList;
import java.util.Collection;

public class TestClass {

    public static int PARENTTYPE=0;
    public static int CHILDTYPE=1;

    ArrayList<ParentClass> parentHolder=new ArrayList<ParentClass>();
    ArrayList<ChildClass> childHolder=new ArrayList<ChildClass>();

    public TestClass(){
        parentHolder.add(new ParentClass());
        childHolder.add(new ChildClass());
    }

    public ArrayList<? extends ParentClass> getHolder(int type){
        if (type==PARENTTYPE){
            return parentHolder;
        }else if (type==CHILDTYPE){
            return childHolder; //<-- no longer incompatible types
        }else{
            throw new RuntimeException("Not a valid type");
        }
    }

    public static void main(String args[]){
        TestClass test=new TestClass();

        ArrayList<? extends ParentClass> col1=test.getHolder(PARENTTYPE);
        ArrayList<? extends ParentClass> col2=test.getHolder(CHILDTYPE);

        ParentClass childCastToParent=col2.get(0);

    }
}

N.B. arraylists have been used for brevity but the same applied to all collections

这篇关于返回集合&lt; ChildType&gt;从指定它返回Collection&lt; ParentType&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆