Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't be as specific with Java generic field types as with generic method types?

Tags:

java

generics

I've got some old command-line argument parsing code I wrote 4 years ago for Java 5, and it won't compile in Java 6 thanks to changes in how generics are handled and/or whether certain library classes are generic. While trying to fix it, I came across the following problem; since it's been 4 years since I've touched Java and I was never an expert at generics to start with, it's sort of stumping me.

The library allows me to specify that certain command-line options correspond to enums. To do this, the ArgumentSpecification object corresponding to this option wants to hold a Class object, which we'll call "enumClass", corresponding to the enum class. Unfortunately, I can't seem to figure out how to properly write the type of that field to constrain it to contain class objects that correspond to actual Enum classes. I think what I want is something like:

protected <E extends Enum<E>> Class<E> enumClass; // compiler error

but the compiler barfs on this. On the other hand, the compiler is completely happy with methods that have return values and/or parameters specified that way:

protected <E extends Enum<E>> Class<E> dummyTest(Class<E> foo) { return foo; } // "works"

I can try using this for the field instead:

protected Class<? extends Enum<?>> enumClass;

but that doesn't really work either...other parts of the code need the "<E extends Enum<E>>" type so they can actually get at E, and this doesn't seem to match up with the "<? extends Enum<?>>", as I get compiler errors like this:

Bound mismatch: The generic method checkedEnumFromString(Class<E>, String) of type EnumUtil is not applicable for the arguments 
 (Class<capture#1-of ? extends Enum<?>>, String). The inferred type capture#1-of ? extends Enum<?> is not a valid substitute for the bounded 
 parameter <E extends Enum<E>>

Is there a way to declare the field with the correct type here that I'm missing? If so, what is it? If not, isn't it horribly broken of Java to be able to declare types in methods that you can't for fields? Or am I so horribly confused that my question makes no sense to start with?

like image 516
Scott Davies Avatar asked Jun 20 '10 06:06

Scott Davies


People also ask

Which reference types Cannot be generic in Java?

Almost all reference types can be generic. This includes classes, interfaces, nested (static) classes, nested interfaces, inner (non-static) classes, and local classes. The following types cannot be generic: Anonymous inner classes .

Which types Cannot be used to initiate a generic type?

1. Which of these types cannot be used to initiate a generic type? Explanation: None.

Which of the following Cannot be parameterized with a type using generics?

Which of these Exception handlers cannot be type parameterized? Explanation: we cannot Create, Catch, or Throw Objects of Parameterized Types as generic class cannot extend the Throwable class directly or indirectly.

How do you restrict the types used as type arguments in generic classes and methods?

Whenever you want to restrict the type parameter to subtypes of a particular class you can use the bounded type parameter. If you just specify a type (class) as bounded parameter, only sub types of that particular class are accepted by the current generic class. These are known as bounded-types in generics in Java.


2 Answers

If you need to define a field with explicit parameter E like that, then you may have to parameterize the type in which the field is declared in. Something like this compiles:

class MyClass<E extends Enum<E>> {
    Class<E> enumClass;
}
like image 158
polygenelubricants Avatar answered Oct 16 '22 20:10

polygenelubricants


You're trying to declare a "generic field" - one which has a type parameter itself. There's no such concept in Java - only methods and types can introduce type parameters.

As polygenelubricants says, you can introduce an extra type parameter in the type itself, and use that as the type of the field.

like image 43
Jon Skeet Avatar answered Oct 16 '22 18:10

Jon Skeet