0

The two add methods in this class have the same erased signature:

class extend
{
  Integer add (Integer a, Integer b)
  {
    return a + b;
  }

  <Type extends Integer> Type add (Type a, Type b)
  {
    return a + b;
  }
}

This makes it impossible to have them both in the same class. The compiler reports the following error:

extend.java:8: error: name clash: add(Type,Type) and add(Integer,Integer) have the same erasure
   Type add (Type a, Type b)
                              ^
  where Type is a type-variable:
    Type extends Integer declared in method add(Type,Type)

But if they are equivalent, why is the unboxing not done in the second case. The compiler reports the following error:

extend.java:10: error: incompatible types
    return a + b;
             ^
  required: Type
  found:    int
  where Type is a type-variable:
    Type extends Integer declared in method add(Type,Type)

In the first case the compiler knows the erased type and in the second case he forgets it again? Why?

ceving
  • 21,900
  • 13
  • 104
  • 178
  • Given that `Integer` is a final class anyway, what benefit is there in having a generic type with a bound of `extends Integer`? I wouldn't be surprised if the language didn't even try to support the addition between two values of a generic type simply because it's not useful. – Jon Skeet Oct 09 '13 at 09:55

1 Answers1

2

Your method <Type extends Integer> Type add (Type a, Type b) can be called with Integer arguments. <Type extends Integer> boundaries allow either a subtype of Integer or Integer. In case someone writes this code:

Integer i = 1;
Integer k = 2;
add(i, k);

It is impossible to determine which method to call, since they both accept integer arguments, and neither is more specific than the other.

If you had add(Integer, Integer) and add(Number, Number) the integer add would be called because it's more specific. But in your case arguments Integer and Integer or subclass are equally specific if an Integer is used.

Also don't expect + operator to work any subclasses. Unboxing is type specific as it looks for specific types, requires an ability to convert to int and instantiate boxed value.

RokL
  • 2,663
  • 3
  • 22
  • 26
  • The question was not why the two methods have the same erasure. And I know that unboxing is type specific. The question was why a plain type and an erased type are not handled in the same way when it comes to unboxing but are handled in the same way when it comes to method signatures. This is an inconsistency in the compiler and I would like to know why it exists? – ceving Oct 09 '13 at 11:03
  • Because type erasures follow a general set of type rules but unboxing concerns itself with specific 6 or so types and your generic type allows for way more types to be used in that spot than just those 6. Unboxing works with Integer, your generic declaration allows for Integer and a bunch of other subtypes which wouldn't work with unboxing, that's why compiler rejects this use. – RokL Oct 09 '13 at 11:36