有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

stringbuilder Java三值运算符不工作?

假设我们有一个StringBuilder和一个double。现在,我想添加双精度。如果double可以表示为整数(例如3.0、5.0等),我想将其添加为整数,否则添加为double

实现这一点的第一种方法是:

StringBuilder sb = new StringBuilder();
double d = 3.5;

if (d % 1 == 0) sb.append((int) d);
else sb.append(d);

System.out.println(sb.toString());

这仍然有效,当d3.0时,3将被追加,如果d3.5时,3.5将被追加

现在我想简单地用三元运算符:

StringBuilder sb = new StringBuilder();
double d = 3.5;

sb.append(d % 1 == 0 ? (int) d : d);

System.out.println(sb.toString());

所以现在我有一个问题,每次,如果double是3.03.5,它将被添加为double值!只有当我在理论上对truefalse施压时,它才有效。。。但每一次,这不是我想要的。这是什么问题?为什么三元运算符不起作用


共 (5) 个答案

  1. # 1 楼答案

    这种行为记录在JLS-15.25中Conditional Operator ? : :

    If one of the operands is of type T where T is byte, short, or char, and the other operand is a constant expression (§15.28) of type int whose value is representable in type T, then the type of the conditional expression is T

    当你写作的时候

    (a > b) ? 'a' : 65
    

    第二种类型被转换为char

    通过JLS,它解释了其他情况下的行为(相同的方法)

  2. # 2 楼答案

    在原语数上使用三元运算符时,第二个和第三个操作数将进行二进制数字升级。在您的例子中,int被强制转换为double。这是在JLS #15.25中指定的

  3. # 3 楼答案

    数值条件表达式是独立表达式(§15.2)

    数值条件表达式的类型确定如下:

    如果第二个和第三个操作数的类型相同,则这就是条件表达式的类型

    如果第二个和第三个操作数中的一个是基元类型T,而另一个的类型是对T应用装箱转换(§5.1.7)的结果,则条件表达式的类型是T

    如果其中一个操作数的类型为byte或byte,而另一个操作数的类型为short或short,则条件表达式的类型为short

    如果其中一个操作数是T类型,其中T是字节、短字符或字符,而另一个操作数是int类型的常量表达式(§15.28),其值可在T类型中表示,则条件表达式的类型是T

    如果其中一个操作数是T类型,其中T是字节、短字符或字符,而另一个操作数是int类型的常量表达式,其值可在U类型中表示,U类型是对T应用取消装箱转换的结果,则条件表达式的类型是U

    否则,二进制数字提升(§5.6.2)将应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型

    这些类型被转换为它们相应的基本类型,称为取消装箱。 如果一个操作数是常数int(在解装箱之前不是整数),其值可在另一种类型中表示,则该int操作数将转换为另一种类型。 否则,较小的类型将转换为下一个较大的类型,直到两个操作数具有相同的类型。转换顺序如下:

    字节->;短->;int->;长->;浮动->;加倍

    char->;int->;长->;浮动->;加倍

    最终,整个条件表达式将获得其第二个和第三个操作数的类型

  4. # 4 楼答案

    这种行为的原因是带有三元运算符的表达式具有定义良好的类型。JLS详细描述了如何计算该类型,但粗略地说,它是冒号之前表达式类型和冒号之后表达式类型的最小上界

    例如,如果bbooleaniintddouble,那么b ? i : d的类型是double,因为doubleintdouble的最小上界。当您在StringBuilder上调用append( b ? i : d )时,您会得到带有double参数的append版本。同样的事情也会发生在你的案例中,比如d % 1 == 0 ? (int) d : d

  5. # 5 楼答案

    我认为编译器将sb.append(d % 1 == 0 ? (int) d : d)视为sb.append(double),否则sb.append((int) d)视为sb.append(int)