Convert from Java primitive to wrapper classes

What amazes me is the behavior of the Java compiler when assigning primitives to shell class references. See code below. Comment lines are not compiled.

I do not understand the logic why:

  • a byte can be assigned byte or Short , but not an Integer or Long link
  • a Short may be assigned byte or Short , but not an Integer or Long reference
  • a int can be assigned byte , Short or Integer , but not a Long reference
  • a Long can be assigned Long , but not byte , Short or Integer reference

I do not see the template. Any understanding of this would be really helpful. Thanks.

 Byte s5 = (byte)7; Short s6 = (byte)7; Integer s7 = (byte)7; // Does not compile Long s8 = (byte)7; // Does not compile Byte s9 = (short)7; Short s10 = (short)7; Integer s11 = (short)7; // Does not compile Long s12 = (short)7; // Does not compile Byte s1 = (int)7; Short s2 = (int)7; Integer s3 = (int)7; Long s4 = (int)7; // Does not compile Byte s13 = (long)7; // Does not compile Short s14 = (long)7; // Does not compile Integer s15 = (long)7; // Does not compile Long s16 = (long)7; 
+5
source share
3 answers

Look at the conversion types allowed in the destination context.

Basically:

Assignment contexts allow you to use one of the following:

  • identity transformation

  • primitive conversion extension

  • link conversion extension

  • box conversion, optionally followed by link conversion extension

  • unboxing conversion, optionally followed by a primitive conversion extension.

(Pay attention to my emphasis on one.)

Most of your examples that don't compile, like

 Integer s11 = (short)7; 

an extension of the primitive transform is required, followed by a box transform. This is not an allowed conversion.

But then you may wonder why the following example compiles:

 Byte s9 = (short)7; 

This is a narrowing of the primitive transform followed by a box transform.

This is a special case:

In addition, if the expression is a constant expression of the type byte , short , char or int [...], narrowing the primitive transform, followed by the box transform, can be used if the Variable Type:

  • byte , and the value of the constant expression is represented in the byte type.

  • short , and the value of the constant expression is represented as short .

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

This particular case is necessary because it is not possible to express an integer literal of a type narrower than int .

+3
source

This is similar to compiler specific behavior. When I embed code in Eclipse, starting Java 7, I do not see the compiler errors that you report for short to Integer or byte to Integer .

Instead, I see byte , short and int all can be assigned byte , short and Integer , but not Long , and Long can only be assigned Long . Interestingly, if you change the variables to primitives instead of wrapper types, the behavior of byte , short and int will not change, but now assignments from other types to Long are also performed.

 javac 1.7.0_02 | byte | Byte || short | Short || int | Integer || long | Long | From byte | Yes | Yes || Yes | Yes || Yes | No || Yes | No | From short | Yes | Yes || Yes | Yes || Yes | No || Yes | No | From int | Yes | Yes || Yes | Yes || Yes | Yes || Yes | No | From long | No | No || No | No || No | No || Yes | Yes | Eclipse Indigo | byte | Byte || short | Short || int | Integer || long | Long | From byte | Yes | Yes || Yes | Yes || Yes | Yes || Yes | No | From short | Yes | Yes || Yes | Yes || Yes | Yes || Yes | No | From int | Yes | Yes || Yes | Yes || Yes | Yes || Yes | No | From long | No | No || No | No || No | No || Yes | Yes | 

Given that different compilers allow different conversions, I suspect that the โ€œcorrectโ€ behavior is not actually written in JLS. It seems that some conversions are done under the covers because the authors of the compiler considered this convenient (for example, byte a = (int)1 allowed, but byte a = (int)1000 not), and not because it is a documentary part of the language.

+2
source

From my research, I found that the byte is a signed 8-bit integer. Shorts are 16-bit integers. Therefore, I can understand why they are compatible, they are both integers with two additions, the emphasis on is signed . Long is a 64-bit integer, but it can also be unsigned (given that it has methods for comparing unsigned lengths). This probably explains why your conversions have been causing errors for a long time - you would have to throw the signed byte into a potentially unsigned one. (Source: reading about primitives at http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html )

0
source

Source: https://habr.com/ru/post/1212675/


All Articles