Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
398 views
in Technique[技术] by (71.8m points)

java - Why is an implicit narrowing conversion allowed from int to byte but not from long to int?

Consider the below code snippet:

// automatic casting works for int to byte conversion as integer literal 127
// is in the range for byte
byte b1 = 127; //OK

// automatic casting doesn't work for long to int conversion 
// even if long literal is in the range of int.
int i5 = 100L; // NOT OK - compilation error

Is there any explanation for such behavior?

Why is explicit conversion not needed in the case of int to byte, but needed for long to int?

The How does Java convert int into byte? question is different. It is about an issue in implicit conversion of int to byte when the int value is out of range.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Widening conversions (eg. byte to int) are generally accepted implicitly by the Java compiler, as there's no loss of information (the range of int is greater than that of byte).

Narrowing conversions (eg. long to int, as in your case) can cause a loss of information, so are generally required to be explicitly casted.

See this similar question, and this. A relevant piece of the Java Language Specification:

Assignment conversion occurs when the value of an expression is assigned (§15.26) to a variable: the type of the expression must be converted to the type of the variable.

...

In addition, if the expression is a constant expression (§15.28) of type byte, short, char, or int:

  • A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.

  • A narrowing primitive conversion followed by a boxing conversion may be used if the type of the variable is:

    • Byte and the value of the constant expression is representable in the type byte

    • Short and the value of the constant expression is representable in the type short.

    • Character and the value of the constant expression is representable in the type char.

(emphasis mine)


Some confusion stems from the fact that we're dealing in particular with constant expressions, as we're using numeric literals. The above spec also needs some careful reading.

To clear some things up and directly answer some of the OP's queries:

  1. Why implicit narrowing is supported for one type of narrowing and not the other?

    Ie. why does byte b1 = 127 work implicitly, while int i5 = 100L not?

    byte b1 = 127 performs an implicit conversion as (cf. the bold text in the above quote), "the value of the constant expression is representable in the type byte". That is, 127 is representable by a byte, so the conversion is implicit. If you try byte b1 = 128, you'll get an error about incompatible types, as 128 isn't representable by byte. The only reason we're allowed an implicit cast here at all is because we're using a constant expression.

    We don't get an implicit conversion in int i5 = 100L (even though 100 is in the range of int) as that's simply not listed in the allowed implicit conversions (the variable's type, int, is not one of byte, short, or char).

    We also don't get an implicit conversion in byte a = 0L, this time as the constant expression is of type long, not of type byte, short, char, or int.

  1. How will a normal programmer know which narrowing conversion is allowed implicitly?

    The implicit narrowing conversions only occur when you're assigning a constant expression to a variable. In these cases, implicit conversions are good as we don't want to be writing code like byte b = (byte)0 all the time. At the same time, we do want to be warned if we write something like byte b = 128, as that doesn't have intuitive behaviour.

    When we're not assigning constant expressions (so eg. int x = 0; byte b = x;), we always want to be warned when we're doing a potentially lossy conversion, as they're dangerous - so explicit conversions in this case also make sense.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...