Returning a Collection from a method that specifies that it returns Collection

后端 未结 1 753
情歌与酒
情歌与酒 2020-12-12 06:50

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 extend

相关标签:
1条回答
  • 2020-12-12 07:34

    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

    0 讨论(0)
提交回复
热议问题