astrogeek14
astrogeek14

Reputation: 234

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!

Upvotes: 0

Views: 180

Answers (1)

SLaks
SLaks

Reputation: 888303

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>.

Upvotes: 1

Related Questions