0

I seem to have painted myself in to a bit of a generics coloured corner. Basically I have a generic Interface X<T1, T2 extends Y<?, ?>> with a bunch of methods, including a T1 getFirstClass(), and a T2 getSecondClass(). This works fine for most things, but one of the things I need to do with this is find instances of this Class that are super classes of what I'm looking up, and I need a "catch-all" object for those that can't be found. This means I end up with a Class that looks like:

public class A implements X<Object, Y<?, ?>> {
    ...
    public Class<Y<?, ?>> getSecondClass() {
        return ????
    }
}

I tried dealing with this by ignoring the <?, ?> bit and using @SuppressWarnings("rawtypes"), which works in Eclipse, but when built by ant, gives the error message type parameter Y is not within its bound. The JDK should be the same - I'm only aware of one being installed on my system, namely 1.6.0_23 (I unfortunately can't update this due to factors beyond my control).

Is there any way I can get around this or am I going to have to go back to the drawing board and redesign my classes?

Vala
  • 5,628
  • 1
  • 29
  • 55
  • Man that seems a very complicated design to me. Also I don't think you can use wildcards in classes or method declarations. Has that changed in Java 7? – Mister Smith Feb 24 '12 at 09:41
  • About your main question, due to type erasure, you can´t return a class of the desired generic type at runtime. You could however work out something by passing a token type in the constructor. – Mister Smith Feb 24 '12 at 09:46
  • I know about type erasure and I don't care. The generics are there for compile time type safety only and will save me dozens of casts while making mistakes less likely. What do you mean passing a token type in the constructor? Oh and Mister Smith - you definitely can use wildcards in classes and method declarations, it works fine in loads of other classes in the same project. – Vala Feb 24 '12 at 10:12
  • I meant you can't declare a class `public class Klazz>, but with extends it is allowed`; About the token, it is just a `Class` instance so that you can return it at runtime, or fork new instances with `Class.newInstance`. – Mister Smith Feb 24 '12 at 12:45

1 Answers1

1

Obviously -- due to erasure -- there's only one Class object Y.class per class declaration Y<F1, ..., FN>. The type of this object is Class<Y>, Y being a raw type. To pass it of as a Class<Y<A1, ..., AN> you need to upcast and then downcast:

return (Class<Y<?, ?>>)(Object) Y.class;

The relevant JLS references you can find in a previous answer to a similar question.

Community
  • 1
  • 1
Ben Schulz
  • 6,101
  • 1
  • 19
  • 15
  • That's what I'm looking for. Thanks! It feels like a hack, but if it makes the rest of the code more readable it may well be worth it. – Vala Feb 24 '12 at 14:24