15

I want to define a method to make sums between different type numbers:

<T> void add (T one, T two)
{
    T res = one + two; 
}

the above method not work because type erasure convert T into Object and thus the + operator is not defined on Object...

How can do that?

Thanks.

xdevel2000
  • 20,780
  • 41
  • 129
  • 196

4 Answers4

20

You'll have to use a bounded type parameter:

public <T extends Number> double add (T one, T two)
{
    return one.doubleValue() + two.doubleValue(); 
}

Note that it uses double as return type because that's the primitive numeric type that covers the largest range of values - and one or both parameters could be double too. Note that Number also has BigDecimal and BigInteger as subclasses, which can represent values outside the range of double. If you want to handle those cases correctly, it would make the method a lot more complex (you'd have to start handling different types differenty).

Paul Bellora
  • 54,340
  • 18
  • 130
  • 181
Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
  • Hmm... What about `BigDecimal` and `BigInteger` ? – Lukas Eder Aug 12 '11 at 09:25
  • 2
    @Lukas: good point; but to correctly handle them would complicate the method enormously. – Michael Borgwardt Aug 12 '11 at 09:35
  • 3
    actually, that is equivalent to `public double add (Number one, Number two)`. the generics has no effect here – newacct Aug 12 '11 at 22:01
  • @newacct: you're right; I started out having it return T, but then there way no way to produce a T as result. – Michael Borgwardt Aug 12 '11 at 22:44
  • 2
    `Long` covers the largest **range** of values, while `Double` covers the largest **domain**. The range `Double` covers is non-monotonic (aka discontinuous), meaning that you use exponents to reach larger values than `Long` will allow, but not all of the intermediate values between any two arbitrary `Double` values. For example, with a `Double` you can reach +/- infinity, but almost none of the values between 2^65 and 2^66 (as a random choice). You should think carefully before using this snippet. – EntangledLoops Oct 24 '16 at 20:48
13

The "simplest" solution I can think of is this (excuse the casting and auto-boxing/unboxing):

@SuppressWarnings("unchecked")
<T> T add(T one, T two) {
    if (one.getClass() == Integer.class) {
        // With auto-boxing / unboxing
        return (T) (Integer) ((Integer) one + (Integer) two);
    }
    if (one.getClass() == Long.class) {
        // Without auto-boxing / unboxing
        return (T) Long.valueOf(((Long) one).longValue() + 
                                ((Long) two).longValue());
    }

    // ...
}

Add as many types you want to support. Optionally, you could handle null as well...

Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
0

Look at this discussion on SO: How to add two java.lang.Numbers?

It's about the same as your problem. Either way, you should not use generics for this, why? Simple: because with generics you couldn't add a Float and a Double, which in general you should be able to do!

Community
  • 1
  • 1
Dorpsidioot
  • 474
  • 2
  • 7
-3
template <class A>
A add (A a, A b)
{
    return (a+b);

}
int main()
{
    int x =10, y =20;
    cout <<"The Integer Addition is " << add(x,y);
    return 0;
}
Shadow
  • 6,161
  • 3
  • 20
  • 14