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.

0

4 Answers 4

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

Sign up to request clarification or add additional context in comments.

5 Comments

Hmm... What about BigDecimal and BigInteger ?
@Lukas: good point; but to correctly handle them would complicate the method enormously.
actually, that is equivalent to public double add (Number one, Number two). the generics has no effect here
@newacct: you're right; I started out having it return T, but then there way no way to produce a T as result.
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.
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...

9 Comments

You probably mean return (T) Integer.valueOf(((Integer) one).intValue() + ((Integer) two).intValue())
Yes, that would be the same, without auto-boxing / unboxing. Thanks for the input. That's more complete now
Why the casting? Why not use a bounded wild as suggested by Michael Borgwardt?
Yes, but I don't want to manually create if/else statements because overloading is a sort of polymorphism so the compiler should automatically understand what to do.
If that's what the original poster wants, then his desires are bad programming practice (tm) as it's asking the method to do too much. Java is not a duck typed language.
|
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!

5 Comments

With generics, you can know the resulting type, though...
Yeah you can, but I feel it requires too much boilerplate code to make it work efficiently.
That depends on how you use it. With java.lang.Number, the boiler-plate code would be outside of the method. With generics, it's inside of the method...
Yeps, you're right about that. And anyways, it's write once and should work all the time, except when new types of numbers arrive =)
I guess we'd all be in trouble when there are new types of numbers :)
-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; } 

4 Comments

This is about Java, not C++... ;-)
According to the tag, the poster is looking for a solution in Java, not in C++.
Seriously sorry for the blooper
Well it shows how C++ has more powerful generics than Java. I wish there was no type erasure in Java :-/

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.