开发者

Confusing Java generics usage: how do I properly parameterize this?

I'm looking at some code with this form:


     1  package com.stackoverflow.java.questions;

     2  import java.util.ArrayList;
     3  import java.util.List;

     4  public class B extends A<B> {
     5      
     6      private
     7      <C extends A>
     8      List<C> getList(Class<C> cls) {
     9          
    10          List<C> res = new ArrayList<C开发者_StackOverflow>();

                 // "snip"... some stuff happening in here, using cls

    11          return res;
    12      }

    13      public
    14      List<A> getList() {
    15          return getList(A.class);
    16      }

    17  }

    18  abstract class A<C extends A<C>> {

    19  }


Yes, I know it's ugly, but I reduced it as much as I could manage.

My question is how do I properly parameterize the use of A on lines 7, 14, and 15?

Currently, I get warnings (A is a raw type. References to generic type A should be parameterized) from Eclipse for lines 7 and 14. I suspect that I would get one for line 15 as well once I fix the other two, but I'm not certain. Either way, it's not currently parameterized and probably ought to be, but I have no idea what the syntax is supposed to be.

Any thoughts on how to add the proper parameter semantics and syntax to get rid of these warnings?

Note: I'm not sure if it matters whether or not A is a recursive generic. I still get the same warnings if I simply use "abstract class A {}" in place of its current definition.

Honestly, if it were my own code I'd change it all to be a heck of a lot simpler. Unfortunately, it's part of an API so I'm trying to change it as little as possible.

Thanks!

UPDATE:

I'm able to address the warnings by parameterizing them as one would expect, but at the cost of an error. It comes down to this, how do I get a Class<A<B>> from an abstract class?

Something like,

Class<A<B>> cls = A.class;

However, this causes a type mismatch error.

UPDATE, part 2:

Turns out, ya just can't do it due to type erasure. See my other question here.


You could start by using <C extends A<B>> and List<A<B>> in those first two instances. Passing a type key is, in this case, counterproductive (see how the cls parameter is never used), so, just strip it out.

(You can always say B.<Foo>getList() to specifically instantiate it with a specific type, assuming you're happy for the type to be non-reified of course.)


Update to incorporate OP's edit: Will using A<?> work for your code? In limited cases, you may not need to fully specify the type. Unfortunately, I don't have your code, so only you can find out whether it'll work.


What exactly do you do here with cls:

// "snip"... some stuff happening in here, using cls

Depending on what you do here, you could possibly replace the Class instance with a Type instance, if you tell me a little more about what you do here I may be able to present you an alternate solution to make it work.


Turns out, ya just can't do it due to type erasure. See my other question here: Java: how do I get a class literal from a generic type?

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜