tags:

views:

858

answers:

7

So, let's say I want to write a class that operates on different kinds of numbers, but I don't a priori know what kind of numbers (i.e. ints, doubles, etc.) I will be operating on.

I would like to use generics to create a general class for this scenario. Something like:

 Adder<Double> adder = new Adder<Double>();
 adder.add(10.0d, 10.0d);   // = 20.0d

But, I cannot instantiate the generic type I pass in to my Adder class! So -- what to do?

+4  A: 

Uh oh---generics are not C++ templates. Because of type erasure, the Double in your example won't even show through to the runtime system.

In your particular case, if you just want to be able to add various types together, may I suggest method overloading? e.g., double add(double, double), float add(float, fload), BigDecimal add(BigDecimal, BigDecimal), etc.

Chris Jester-Young
0 vote down Thanks, Chris. But, seriously, I have a big class that needs to perform the same (large number of) operations on different kinds of Numbers. Are you saying it's back to the copy-and-paster for me?
Jake
A: 

Thanks, Chris. But, seriously, I have a big class that needs to perform the same (large number of) operations on different kinds of Numbers. Are you saying it's back to the copy-and-paster for me?

Jake
You might want to add this as a comment to Chris' post, since posts will change their ordering by StackOverflow design.
Paul Brinkley
And then delete this answer.
MatrixFrog
+2  A: 

I think you can do what you want, but I'm not sure, given the information you provided. It sounds as if you want some variation of the following:

public class Foob<T extends Number> {

    public T doSomething(T t1, T t2) {
     return null;
    }
}
Paul Brinkley
A: 

If you don't know what kinds of numbers you'll be operating on, then you probably won't be using instance variables of your own. In that case, you can write static methods and never need to instantiate your class.

If you really need your own intermediate variables, then you will likely need to define them differently for each class of user variables you're working with. For instance, if someone tries to use your class to operate on BigDecimal variables, you probably won't be using int variables for intermediate results.

Ken Paul
A: 

I'm not sure generics is what you want here. Generics in java are for enforcing compile-time constraints, not runtime polymorphism. I think what you really want is to use overloading. Using generics, you would have something like:

interface Adder<T> {
   T add(T arg1, arg3);
}

and a bunch of:

class DoubleAdder implements Adder<Double> {
   Double add(Double arg1, Double arg2) {
      return arg1.add(arg2);
   }
}

and then a bunch of:

if (arg1 instanceof Double) {
   Adder<Double> adder = new DoubleAdder();
}

Using generics doesn't save you anything.

Laplie
A: 

I agree with Laplie. Overloading is what will help you. The closest you can come using generics is something like this:

public class NumericOps
{
  public T add(T n1, T n2) {
    //n1.add(n2);
    //This is not possible because Number does not have an add method, hence
    //you will have to determine the type of n1.
    //We cannot determine the type of U because it will not exist at runtime
    //due to type erasure
    if(n1 instanceof Integer) {
      //add the Integers...
    }
    else if(n1 instanceof Double) {
      //add the doubles
    }
    return null;
  }
}

But this does not help very much because there is no benefit of using generics.

Parag
A: 

If you could live with converting everything to a double for the computation you could use polymorphism

Number someNumberFunction(Number n1, Number n2) 
{
  double
      d1 = n1.doubleValue(),
      d2 = n2.doubleValue();

  /* perform computations on d1 & d2 */
}

Unfortunately this won't work well on BigInteger or BigDecimal

Graphics Noob