无法使用&#34;(expr)设置短值?<val1>:<val2>&#34; Java中的符号</val2> </val1>

时间:2014-05-15 16:45:47

标签: java

我遇到了一个我不太了解的奇怪问题,但它并不是我节目的一个显示器。我根据条件的结果设置short变量的值,如果我使用标准if / else但是如果我使用速记条件赋值则不能正常工作。

这是一个简单的例子:

public class ShortTest {
    public static void main(String args []) {
        int i = 0;
        short s = 0;

        // This always works
        if( i < 100 )
            s = 0;
        else
            s = 1;

        // This causes an error
        s = (i < 100)?1:0;
    }
}

编译此代码会产生以下结果:

ShortTest.java:13: error: possible loss of precision
                s = (i < 100)?1:0;
                             ^
  required: short
  found:    int
1 error

但是,如果您向short1或两者添加强制转换,那么它可以正常工作。所有这三个陈述都有效:

0

s = (i < 100)?(short)1:0;

s = (i < 100)?1:(short)0;

这不是什么大问题,因为if / else很好,但这让我疯了。有没有理由说这些值在短时间条件下无法自动从s = (i < 100)?(short)1:(short)0;投射到int?为什么只是其中一个突然使整个声明有效?任何见解将不胜感激!

2 个答案:

答案 0 :(得分:5)

这里将

10视为文字int值,此操作的结果为int,编译器无法缩小此范围。您应该明确添加一个强制转换:

s = (short) ((i < 100)? 1:0);

Java Language Specification. Chapter 15. Expressions. 15.25. Conditional Operator ?.

中对此进行了解释
  

条件运算符有三个操作数表达式。 ?出现在第一个和第二个表达式之间,:出现在第二个和第三个表达式之间。

     

(...)

     

如果第二个和第三个操作数表达式都是数值表达式,则条件表达式是数字条件表达式。

     

(...)

     

数字条件表达式是独立表达式(第15.2节)。

     

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

     
      
  • 如果第二个和第三个操作数具有相同的类型,那么这就是条件表达式的类型。

  •   
  • 如果第二个和第三个操作数之一是原始类型T,而另一个操作数的类型是将装箱转换(第5.1.7节)应用于T的结果,那么条件表达式的类型是吨。

  •   
  • 如果其中一个操作数的类型为字节或字节,另一个操作数的类型为short或Short,则条件表达式的类型很短。

  •   
  • 如果其中一个操作数是T类型,其中T是byte,short或char,另一个操作数是int类型的常量表达式(第15.28节),其值可在类型T中表示,那么条件表达式的类型是T.

  •   
  • 如果其中一个操作数是T类型,其中T是Byte,Short或Character,另一个操作数是int类型的常量表达式,其值可以在U类型中表示,它是U的结果。将取消装箱转换应用于T,则条件表达式的类型为U。

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

  •   
     

请注意,二进制数字促销执行值集转换(第5.1.13节)并可执行拆箱转换(第5.1.8节)。

答案 1 :(得分:0)

添加一些细节:正如已经指出的,整数文字总是具有类型int(当没有L后缀时)。这样的陈述:

s = 1;  // where s is short
因此,

执行从intshort的缩小转化。通常,这种转换不会自动进行。但是,JLS的第5.2节有一些适用于常量表达式的特殊规则:

  

此外,如果表达式是byte,short,char或int类型的常量表达式(第15.28节):

     
      
  • 如果变量的类型是byte,short或char,则可以使用缩小的基元转换,并且常量表达式的值可以在变量的类型中表示。

  •   
  • 如果变量的类型为:

    ,则可以使用缩小的基元转换,然后进行装箱转换。      
        
    • 字节和常量表达式的值可以在类型字节中表示。

    •   
    • 简短,常量表达式的值可以在短类型中表示。

    •   
    • 字符和常量表达式的值可以在char类型中表示。

    •   
  •   

这意味着这也是合法的:

s = 1 + 2;

但不幸的是不是这样:

s = (i < 100) ? 1 : 0;

因为右边的表达式不符合常量表达式的定义。从理论上讲,§5.2可以允许这种情况,通过将常量表达式应用于条件表达式,其中第二个和第三个操作数都是常量表达式(或条件表达式,允许,递归)。是否值得将此视为语言变化,我无法分辨。