开发者

Java: upcasting Collection<T> to Collection<U super T>

开发者 https://www.devze.com 2022-12-12 13:50 出处:网络
I have a Collection<T>. I have a class TManager imp开发者_如何学Clementing an interface UManager which has a method getCollection() that needs to return a Collection<U> where U is an inter

I have a Collection<T>. I have a class TManager imp开发者_如何学Clementing an interface UManager which has a method getCollection() that needs to return a Collection<U> where U is an interface, and T is a class that implements U.

Aside from just casting it, e.g. return (Collection<U>)Tcoll;, is there a more correct way to handle this?

I control all 4 classes/interfaces here. Am I wrong in declaring UManager.getCollection as

public Collection<U> getCollection();

Should it be

public Collection<? extends U> getCollection()

?


It depends on what you need to do with the Collection. If you don't need to put anything into the returned collection, then use the extends parameter

  public interface UInterface {

         Collection<? extends UInterface> getCollection();

  }

And be done with it. If in the future you do need to add to the collection, wrapping it in a new Collection and adding all does the job, ignore the performance for nothing hit of it (extra run time performance hit for a compile time issue).

If, however, the purpose is to return a mutable collection, then you can add a type parameter to your interface:

 public interface UInterface<T extends UInterface> {

        Collection<T> getCollection();

 }

Then your implementation would be:

 public class TClass implements UInterface<TClass> {

        pubic Collection<TClass> getCollection();

 }

The problem with this approach is that you absolutely must have a type parameter at runtime to use the interface to get a mutable collection out of it, or be referencing the concrete class.


It should be:

public Collection<U> getCollection();

Try to avoid bounded wildcards in return types.

Subclasses would just declare the returned reference type as Collection<U> rather than Collection<T>. That would eliminate your casts.

However, if you do see the need to have a bounded wildcard in the return type, then I guess you will have to return Collection<? extends U> and won't need the cast.


i believe you want:

public Collection<? extends U> getCollection();

You can find some official docs about this here.

@Jason, you're right. The doc doesn't call out return types explictly, but it does work. Here's an example method that demonstrates the syntax:

public Collection<? extends Throwable> getErrors() {
    return new ArrayList<Exception>();
}


Your topicstart was a bit confusing because one-character identifiers are usually used by generic types but you explicitly mentioned about an interface and a class. So are you looking for something like this?

interface UManager<T extends UInterface> {
    Collection<T> getCollection();
}

class TManager implements UManager<TClass> {
    public Collection<TClass> getCollection() {
        return Arrays.asList(new TClass(), new TClass());
    }
}

interface UInterface {

}

class TClass implements UInterface {

}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号