Is it possible to write a general +1 method for numeric box types in Java?

This is NOT homework.

Part 1

Is it possible to write a general method, for example:

<T extends Number> T plusOne(T num) {
    return num + 1; // DOESN'T COMPILE! How to fix???
}

With the exception of the use of the beam instanceofand drops, is this possible?


Part 2

The following 3 methods compile:

Integer plusOne(Integer num) {
    return num + 1;
}   
Double plusOne(Double num) {
    return num + 1;
}
Long plusOne(Long num) {
    return num + 1;
}

Is it possible to write a general version that Tonly binds to Integer, Doubleor Long?

+5
source share
7 answers

Part 1

There is no satisfactory solution for this, since it java.lang.Numberdoes not indicate anything that would be useful for calculating the successor Number.

instanceof . , instanceof Number, , . BigInteger, AtomicLong Number (, Rational ..).

2

, , . 3 , autoboxing/unboxing , -:

Integer plusOne(Integer);
  Code:
   0:   aload_1
   1:   invokevirtual   #84; //int Integer.intValue()
   4:   iconst_1
   5:   iadd
   6:   invokestatic    #20; //Integer Integer.valueOf(int)
   9:   areturn

Double plusOne(Double);
  Code:
   0:   aload_1
   1:   invokevirtual   #91; //double Double.doubleValue()
   4:   dconst_1
   5:   dadd
   6:   invokestatic    #97; //Double Double.valueOf(double)
   9:   areturn

Long plusOne(Long);
  Code:
   0:   aload_1
   1:   invokevirtual   #102; //Long Long.longValue()
   4:   lconst_1
   5:   ladd
   6:   invokestatic    #108; //Long Long.valueOf(long)
   9:   areturn

xxxValue() valueOf() , , 1 , (iconst_1, dconst_1 lconst_1).

<T=Integer|Long|Double>, , .

+6

Number autounboxed. , BigDecimal autounboxed. "+" .

+5

, Number ( JDK):

  • String
  • , BigDecimal

Generics, :

public class Test {

    @SuppressWarnings("unchecked")
    public static <T extends Number> T plusOne(T num) {
        try {
            Class<?> c = num.getClass();
            Constructor<?> constr = c.getConstructor(String.class);
            BigDecimal b = new BigDecimal(num.toString());
            b = b.add(java.math.BigDecimal.ONE);
            return (T) constr.newInstance(b.toString());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        System.out.println(plusOne(1));
        System.out.println(plusOne(2.3));
        System.out.println(plusOne(2.4E+120));
        System.out.println(plusOne(2L));
        System.out.println(plusOne(4.5f));
        System.out.println(plusOne(new BigInteger("129481092470147019409174091790")));
        System.out.println(plusOne(new BigDecimal("12948109247014701940917.4091790")));
    }

}

, , T T, , .

+4

FWIW - .

+ . , Integer Long, / . Number , , , . , generics , :

public Number plusOne(Number num) {
    return num + 1;
}
+2

1:

num + 1 ? + . :

Integer n = plusOne(anotherInt);

:

Integer n = anotherInt + 1;

- .

+1

, , , . Java , , , , .

Java , . : ", , , , , String, ". ++, , .

, , - plusOne, Number, .

+1

Java . unboxing ..

For such a simple case as yours, I suggest using only primitives.

0
source

All Articles