Puzzle 24: Enjoy every byte

Source: Internet
Author: User

The following program cyclically traverses byte values to find a specific value. What will this program print?

public class BigDelight {    public static void main(String[] args) {        for (byte b = Byte.MIN_VALUE; b < Byte.MAX_VALUE; b++) {             if (b == 0x90)                 System.out.print("Joy!");        }    }}

This loop iterates all byte values except byte. max_value to find 0x90. This value is suitable for byte representation and is not equal to byte. max_value. Therefore, you may think that this loop will find it once in this iteration and print out joy !. However, what you see is virtual. If you run the program, you will find that it does not print anything. What's going on?

In short, 0x90 is an int constant, which is out of the byte value range. This is contrary to intuition, because 0x90 is a two-digit hexadecimal literal constant, each of which occupies four bits, therefore, the entire value occupies only eight bits, that is, one byte. The problem is that byte is signed. The constant 0x90 is the 8-bit int value of a positive highest bit. The valid byte value ranges from-128 to + 127, but the int constant 0x90 equals to + 144.

Comparing a byte with an int is a mixed-type comparison ). If you think of the byte value as an apple and the int value as an orange, the program is comparing the apple and the orange. Consider the expression (byte) 0x90 = 0x90). Although the appearance looks true, It is equal to false.

To compare the byte values (byte) 0x90 and INT values 0x90, Java expands the original type conversion to an int [JLS 5.1.2], and then compares the two int values. Because byte is a signed type, this conversion is performed by the symbol extension, which increases the negative byte value to an equal int value on the number. In this example, the conversion is to increase (byte) 0x90 to the int value-112, which is not equal to the int value 0x90, that is, + 144.

Since the system always forcibly promotes an operand to a type that matches another operand, it is easy to confuse mixed types. This conversion is not visible and may not produce the expected results. There are several methods to avoid mixed type comparison. Let's continue with the comparison of fruits. You can compare apples with apples, or compare oranges with oranges. You can convert int to byte, and then you can compare one byte with another:

if (b == (byte)0x90)    System.out.println("Joy!");

Alternatively, you can use a shielding code to eliminate the influence of symbol extension and convert byte to int. Then you can compare one int with another:

if ((b & 0xff) == 0x90)    System.out.print("Joy!");

The above two solutions can run normally, but the best way to avoid such problems is to remove the constant value out of the loop and define it in a constant declaration. The following is our first attempt:

public class BigDelight {    private static final byte TARGET = 0x90;       public static void main(String[] args) {        for (byte b = Byte.MIN_VALUE; b <              Byte.MAX_VALUE; b++) {             if (b == TARGET)                 System.out.print("Joy!");        }    }}

Unfortunately, it cannot be compiled at all. If there is a problem with the constant declaration, the compiler will tell you the problem: 0x90 is not a valid value for the byte type. If you want to revise the statement as follows, the program will run very well:

Private Static final byte target = (byte) 0x90;

In short, avoid mixing type comparisons because they are inherently confusing (puzzle 5 ). To help achieve this goal, replace "magic number" with declared constants ". You have learned that this is indeed a good idea: it illustrates the meaning of a constant, aggregates the definition of a constant, and contains only repeated definitions at the root. Now you know that it can also force you to assign a suitable type for each constant, eliminating a root cause of mixed type comparison.

The lesson of language design is that the extension of byte values is a common source of bugs and chaos. The shielding mechanism required to offset the symbol extension effect will make the program appear chaotic and unordered, thus reducing the readability of the program. Therefore, the byte type should be unsigned. You can also consider providing a mechanism to define literal constants for all original types, which reduces the need for easy-to-produce-Wrong type conversions (puzzle 27 ).

Puzzle 24: Enjoy every byte

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.