为什么允许从int到byte而不是从long到int的隐式缩小转换?

时间:2017-12-29 16:00:53

标签: java

请考虑以下代码段:

...
<div class="row">
  <div class="col-md-12">
    <%= @page.videos.each do |v| %>
      <iframe width="560" height="315" src="https://www.youtube.com/embed/<%= v.youtube %>" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen></iframe>
    <% end %>
  </div>
</div>
...

这种行为有什么解释吗?

为什么在int到byte的情况下不需要显式转换,但需要long to int?

How does Java convert int into byte?问题不同。当int值超出范围时,它是关于int到byte的隐式转换的问题。

2 个答案:

答案 0 :(得分:11)

Java编译器通常会隐式接受扩展转换(例如byteint),因为没有信息丢失(int的范围大于byte的范围{1}})。

缩小转化次数(例如。longint,如您所述)可能会导致信息丢失,因此通常需要明确投放。

请参阅this类似问题和thisJava Language Specification的相关部分:

  

当表达式的值被赋值(第15.26节)给变量时,就会发生赋值转换:必须将表达式的类型转换为变量的类型。

     

...

     

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

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

  •   
  • 如果变量的类型为:

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

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

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

    •   
  •   

(强调我的)

由于我们正在使用数字文字,因此我们特别处理常量表达式这一事实引发了一些混淆。以上规范也需要仔细阅读。

清除一些内容并直接回答OP的一些问题:

  1. 为什么一种缩小而不是另一种缩小支持隐式缩小?

    IE中。为什么byte b1 = 127隐式工作,而int i5 = 100L没有?

    byte b1 = 127执行隐式转换(参见上面引用中的粗体文本),“常量表达式的值可在类型字节中表示”。也就是说,127可由byte表示,因此转换是隐含的。如果您尝试byte b1 = 128,则会收到有关不兼容类型的错误,因为128无法表示byte。我们允许隐式转换在所有的唯一原因是因为我们使用常量表达式

    我们在int i5 = 100L中没有获得隐式转换(即使100在int范围内),因为它只是在允许的隐式转换中没有列出(变量的类型,{{1 }},不是intbyteshort)之一。

    我们也没有在char中获得隐式转换,因为常量表达式的类型为byte a = 0L,而不是long类型,byte,{ {1}}或short

    1. 普通程序员如何知道隐含允许哪种缩小转换?

      只有在为变量指定常量表达式时,才会发生隐式缩小转换。在这些情况下,隐式转换很好,因为我们不想一直编写像char这样的代码。与此同时,如果我们写int之类的内容,我们会被警告,因为它没有直观的行为。

      当我们没有分配常量表达式时(例如。byte b = (byte)0),我们总是希望在我们进行潜在有损转换时收到警告,因为它们很危险 - 在这种情况下如此明确的转换也有意义。

答案 1 :(得分:-5)

您必须手动投射

int i5 = (int)100L; 

因为long类型有8个字节......