astrogeek14 astrogeek14 - 1 month ago 10
Java Question

Java Generics: Generics not within bounds at initialization

I am working with generics in Java™, and have found that I have a slight problem. I know Java™ uses type erasure; however, I need to get the class of the generic at run-time. Therefore, I use a simple runaround to find the class of the generic, described here. The issue I am having is when I compile,

javac
spits out this:

C:\blah\Board.java:65: error: type argument T#1 is not within bounds of type-variable T#2
this.boardManager = new NumberBoardManager<T>(c);
^
where T#1,T#2 are type-variables:
T#1 extends Comparable<? super T#1> declared in class Board
T#2 extends Number,Comparable<? super T#2> declared in class NumberBoardManager
C:\blah\Board.java:65: error: constructor NumberBoardManager in class NumberBoardManager<T#2> cannot be applied to given types;
this.boardManager = new NumberBoardManager<T>(c);
^
required: Class<T#1>
found: Class<CAP#1>
reason: actual argument Class<CAP#1> cannot be converted to Class<T#1> by method invocation conversion
where T#1,T#2 are type-variables:
T#1 extends Comparable<? super T#1> declared in class Board
T#2 extends Number,Comparable<? super T#2> declared in class NumberBoardManager
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ?


The first error makes sense, as the class I am in,
Board
has a generic that only extends
Comparable<? super T>
, while this specific constructor uses the fact that I want (but not necessarily have) a generic that also extends
Number
. I want to fix this issue by having the generic I use to create the
boardManager
to extend both
Number
and
Comparable<? super T>
, and to error out if the generic doesn't extend
Number
. But I don't know of any syntax which would help me at this point.

The second error is caused because I have already initialized
boardManager
with the generic
T
. But if we know
T
implements
Comparable<? super T>
, why does this error get thrown? I hope with the solving of the first issue, that the second issue is taken care of as well. Here is some code to provide context, and I am willing to provide more if you are still confused.

Board.java



public class Board<T extends Comparable<? super T>> extends Object implements Serializable
{
private BoardManager<T> boardManager;

public Board(int size)
{
Class<?> c = ((Class<?>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
if(c.isAssignableFrom(Number.class))
{
this.boardManager = new NumberBoardManager<T>(c); //this is the line
}
}
}


NumberBoardManager.java



public class NumberBoardManager<T extends Number & Comparable<? super T>> extends Object implements BoardManager<T>, Serializable
{
private Class<T> c;

public NumberBoardManager(Class<T> c)
{
this.c = c;
}
}


Any and all help would be appreciated!

Answer

I want to fix this issue by having the generic I use to create the boardManager to extend both Number and Comparable, and to error out if the generic doesn't extend Number.

You can't do that.

You can't have methods on a class that are only allowed with certain type parameterizations; the class must be able to fully function with any allowed type parameter.

You need to constrain the entire Board class to have T be Number.

The other error is because Class<?> isn't compatible with Class<T>. <?> means that the type parameter might be any possible type; it might be something that violates T's constraint.
You need to cast to Class<T>.