2

I have the following example:

public class main3
{
  static class Value<T>
  {
    T value;
    Value (T value) { this.value = value; }
  }

  static class IntegerValue extends Value<Integer>
  {
    IntegerValue (Integer value) { super (value); }
    IntegerValue (String value)  { super (Integer.valueOf (value)); }
  }

  static <T> IntegerValue integer (T value) { return new IntegerValue(value); }

  public static void main (String ...argv)
  {
    IntegerValue a = new IntegerValue (42);
    IntegerValue b = new IntegerValue ("42");

    IntegerValue c = integer (42);
    IntegerValue d = integer ("42");
  }
}

This fails with the error:

main3.java:15: error: no suitable constructor found for IntegerValue(T)
  static <T> IntegerValue integer (T value) { return new IntegerValue(value); }
                                                     ^
    constructor IntegerValue.IntegerValue(Integer) is not applicable
      (argument mismatch; T cannot be converted to Integer)
    constructor IntegerValue.IntegerValue(String) is not applicable
      (argument mismatch; T cannot be converted to String)
  where T is a type-variable:
    T extends Object declared in method <T>integer(T)
1 error

How to specify the right type of T when calling the generic integer method?

I tried also this:

    IntegerValue c = main3.<Integer>integer (42);
    IntegerValue d = main3.<String>integer ("42");

But it does not help.

ceving
  • 21,900
  • 13
  • 104
  • 178

1 Answers1

4

There are only 2 constructors available for IntegerValue: IntegerValue(Integer) and IntegerValue(String).

Therfore, what you want is not possible. Well, in theory you can write:

static <T extends Integer> IntegerValue integer(T value) { ... }

but creating a typevar whose lower bound is a final class is obviously quite completely useless.

I surmise that what you want is that you have a single method, and that you can pass either an Integer or a String into this method.

That's not what generics are for, and that is not possible with generics.

The closest you can get is:

    static IntegerValue integer(String value) { return new IntegerValue(value); }
    static IntegerValue integer(Integer value) { return new IntegerValue(value); }
rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • The two methods differ just by the type. Why is it not possible to unify them by the use of a type variable? – ceving Sep 04 '20 at 13:56
  • I'd have to write half a book to delve into the specifics, and a delve into 25 years of history as to why it happened that way. The conclusion is that it just isn't. – rzwitserloot Sep 04 '20 at 14:10