编程语言
首页 > 编程语言> > 是否可以为Java中的数字框类型编写通用的1方法?

是否可以为Java中的数字框类型编写通用的1方法?

作者:互联网

This is NOT homework.

第1部分

是否可以编写通用方法,如下所示:

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

如果不使用一堆instanceof和casts,这可能吗?

第2部分

编译以下3种方法:

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

是否可以编写将T仅绑定到Integer,Double或Long的通用版本?

解决方法:

第1部分

对此没有令人满意的解决方案,因为java.lang.Number没有指定任何对计算Number的后继有用的东西.

您必须对数字框类型进行instanceof检查,并专门处理每种情况.另请注意,您可能会获得Number的instanceof,该实例不是数字框类型,例如BigInteger,AtomicLong和Number的可能未知的子类(例如Rational等).

第2部分

看起来很欺骗,在这里.这三种方法看起来很相似,但是自动装箱/拆箱隐藏了以下事实:它们在字节码级别上实际上有很大的不同:

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

这3种方法不仅在不同类型上调用不同的xxxValue()和valueOf()方法,而且将常数1推入堆栈的指令也不同(iconst_1,dconst_1和lconst_1).

即使可以绑定< T = Integer | Long | Double>之类的通用类型,这3种方法也不能通用化为一种方法,因为它们包含非常不同的指令.

标签:bounded-wildcard,java,generics
来源: https://codeday.me/bug/20191010/1888539.html