0

I have a problem with returning generic collection from getter method. My class looks like this:

public abstract class ContentGroup<E extends Content> extends Content {

    private List<E> childContents = new LinkedList<E>();

    public List<E> getChildContents() {
        return childContents;
    }
    ...
}

public class Container extends ContentGroup {

} 

When I call getChildContents() method it returns a list, but not a list of objects extending Content class so I have to explicitly cast returned value to Content:

public void doit(Container contentGroup) {

    //Why does get method return Object instead of Content?
    Content content = (Content) contentGroup.getChildContents().get(0); 
    ...
} 

Edit

I updated the code to reflect better the acctual implementation. As one of the answers suggests the problem was that Container did not define Type. Problem was solved with:

public class Container extends ContentGroup<Content> {

} 
Maciej Donajski
  • 298
  • 2
  • 13
  • possible duplicate of [What is a raw type and why shouldn't we use it?](http://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it) – Joe Aug 16 '14 at 14:23
  • 3
    `do` is a keyword in Java. Can't be used as identifier (method name) – Braj Aug 16 '14 at 14:25
  • 1
    What if you change the signature to `_do(ContentGroup> contentGroup)` ? – kajacx Aug 16 '14 at 14:27
  • share complete code where this method is defined. – Braj Aug 16 '14 at 14:31
  • I changed method invocation fragment to simplify code (unfortunately from infinite number of possibilities to name a method I picked java keyword). Already edited the question. – Maciej Donajski Aug 16 '14 at 14:54

2 Answers2

2

You have mixed Generic with Raw Type

Have a look at the method arguments, It's not Generic.

public void do(ContentGroup contentGroup) { // RAW type is used

It should be generic as well otherwise at runtime you would encounter an exception while casting.

Braj
  • 46,415
  • 5
  • 60
  • 76
1

To complete user3218114's answer, you should do something like this:

class Content {
}

class ExtendedContent extends Content {

    void foo() {
    }
}

abstract class ContentGroup<E extends Content> extends Content {

    private List<E> childContents = new LinkedList<E>();

    public List<E> getChildContents() {
        return childContents;
    }
}

class ExtendedContentGroup extends ContentGroup<ExtendedContent> {
}

public class Toto {

    public <E extends Content> E toto(ContentGroup<E> contentGroup) {
        return contentGroup.getChildContents().get(0); 
    }

    public void bar() {
        ExtendedContent extendedContent = toto(new ExtendedContentGroup());
        extendedContent.foo();
    }
}

Also note that I did get a compilation error because do is a reserved word in Java (could come from my IDE settings though, not 100% sure of that), so I suspect you should rename your function (toto in my case).

ratiaris
  • 327
  • 2
  • 10