“generic method” “absolute value” java

2019-08-09 02:44发布

问题:

I want to make a stupid example for my students, but a don´t know if I can do what I´m thinking

I want to do the abs method with generics.

My idea is something similar to this:

public class MiMath {
  public static <T extends Number> T abs(T objeto) {
    if (objeto.doubleValue()<0)
        return (T) -objeto.doubleValue();
    else
        return  objeto;
  }
}

in this linea

return (T) -objeto.doubleValue(); 

eclipse says that (T) is not a Type

回答1:

The problem is that what you are doing here with the (T) is not really a cast, behind the scenes it is using autoboxing and calling T.valueOf() - which generics doesn't know about.

For a good example of generics you are much better off using things like collections (since they are also the place people are most likely to use them).



回答2:

Your motivation is to return an object of the same type as the one it was called with.

Unfortunately, Generics cannot help you there. On your line

return (T) -objeto.doubleValue();

you would actually have to say

return new T(-objecto.doubleValue());

but that can't work because T is not known at compile time, and that is when the decision about it must be made.

A way to get a similar result, but with far less elegance, would be to have an interface

public interface AbsEvaluator<N extends Number> {
    N abs(N n);
}

and have implementations like

AbsEvaluator<Integer> intAbs = 
  new AbsEvaluator<Integer>() { public Integer abs(Integer n) { return -n; }};

The implementation would be exactly the same for each type, so the scheme is quite weak.

Good examples which rely on type inference of the kind you are looking for are higher-order functions (of course, Java doesn't have first-class functions, so you have to model them with one-method interfaces). Then you could, for example, have

<T,U,V> Function<T, V> compose(Function<U, V> g, Function<T, U> f);

Not exactly beginner's stuff, especially when implementations are also shown, but maybe it fits into your curriculum. Note that this kind of stuff will become very prominent when Java 8 gets released.



回答3:

The generics information (T) exists only at compile time, and is discarded after compile.

Therefore you can never cast to a generic at run time, which is what your return statement does.