Java's often forgotten things
2012-10-17 18:38:57 | Category: java | Tags: | report | font size subscription
For beginners who are new to Java ,the basics ofJava are something we must learn carefully, but in the case of a veteran who has been working for a few years, java is sometimes The basic knowledge of the question, for this uncertainty, and it is easy to confuse the knowledge point,Java doubts have been a good summary for everyone, now borrow a summary of the author, to make a list, I hope to be helpful to you.
1. Parity judgment
Do not use I% 2 = = To determine whether it is odd, because I is negative odd when not set, please use I 2! = zero to determine whether it is odd, or use
High-Efficiency (I & 1)! =% to judge.
2. Accurate calculation of Java code in decimals
- System.out.println (2.00-1.10);//0.8999999999999999
The above calculated result is not 0.9, but a series of decimals. The problem is that the number 1.1 cannot be accurately represented as a double, so it is
As the nearest double value, the program subtracts 2 from this value, but the result of this calculation is not the double value closest to 0.9.
Generally, the problem is that not all decimals can be accurately represented by binary floating-point numbers.
Binary floating-point is very unsuitable for currency calculations because it is not possible to represent 1.0 to any other negative power of 10.
The first way to solve the problem is to use the smallest unit of currency (min) to represent:
Java code
- System.out.println (200-110);//90
The second way is to use BigDecimal, but be sure to use the BigDecimal (String) constructor, and never use a bigdecimal (double) to construct (
You cannot convert a float or double to a string and then use BigDecimal (string) to construct it, because converting a float or double to a string
When the accuracy is lost). For example, new BigDecimal (0.1), it will return a BigDecimal, i.e.
0.1000000000000000055511151231257827021181583404541015625, the correct use of BigDecimal, the program can print out our period
Look at the result of 0.9:
Java code
- System.out.println (New BigDecimal ("2.0"). Subtract (New BigDecimal ("1.10"));//0.9
Also, if you want to compare the size of two floating-point numbers, use the BigDecimal CompareTo method.
If you would like to know more about it, please refer to "Floating point number analysis in Java"!
3. int integer multiplication Overflow
We calculate the number of microseconds in a day:
Java code
- Long Microsperday = 24 * 60 * 60 * 1000 * 1000;//correct result should be: 86400000000
- System.out.println (microsperday);//actually: 500654080
The problem is that it overflows during the calculation. This formula is executed entirely in int, and only after the operation is completed will the result be promoted to
Long, which is already too late: the calculation has overflowed.
The workaround causes the first factor of the evaluation expression to be explicitly long, which forces all subsequent computations in the expression to be done with a long operation, which
Results will not overflow:
Java code
- Long Microsperday = 24L * 60 * 60 * 1000 * 1000;
4. Negative hexadecimal and octal literal constants
The "Numeric literal constants" are of type int, regardless of whether they are binary, so "2147483648", "0x180000000" (16 binary, total 33
The value range of the integer) "Literal constant is wrong, compile will be reported over int's range of values, so to determine a long to represent
"2147483648L", "0x180000000l".
Decimal literal constants have only one attribute, that is, all decimal literal constants are positive, if you want to write a negative decimal, you need to be in the positive decimal
Literal constants are preceded by a "-".
hexadecimal or octal literal constants may not necessarily be positive or negative, or positive, or minus, depending on the current situation: if the hexadecimal and octal characters
The highest bits of a polygon constant are set to 1, so they are negative:
Java code
- System.out.println (0x80);//128
- 0X81 is considered an int, the highest bit (32nd bit) is 0, so it is a positive number
- System.out.println (0x81);//129
- System.out.println (0x8001);//32769
- System.out.println (0x70000001);//1879048193
- The literal 0x80000001 is of type int, the highest bit (32nd bit) is 1, so it is a negative number
- System.out.println (0x80000001);//-2147483647
- Literal 0x80000001l is forced to long, the highest bit (64th bit) is 0, so it is a positive number
- System.out.println (0x80000001l);//2147483649
- Minimum int type
- System.out.println (0x80000000);//-2147483648
- As long as more than 32 bits, you need to add l to long after literal constant, or compile error
- System.out.println (0x8000000000000000l);//-9223372036854775808
As can be seen from the above, the hexadecimal literal constant represents the int type, if more than 32 bits, you need to add "L" later, otherwise compiled. Such as
The result is 32, negative int positive, more than 32 bits, or long, but must be explicitly specified as long.
Java code
- System.out.println (long.tohexstring (0x100000000l + 0xcafebabe));//Cafebabe
Why not 0x1cafebabe? The addition of the program execution is a mixed-type calculation: The left operand is long, and the right operand is the int type
。 To perform this calculation, Java promotes the numeric value of type int to a long type with a widening primitive type conversion, and then adds the two long values. Because
int is a signed integer type, so this transformation performs a symbol extension.
The right operand of this addition, 0xcafebabe, is 32 bits and will be promoted to a long value of 0xffffffffcafebabeL, after which the value is added to the Zoka
For 0x100000000l. When treated as an int type, the high 32 bits of the right operand after the symbol extension are-1, and the 32nd bit of the left operand is 1, two digits
The values are added 0:
0x 0xffffffffcafebabeL
+0x 0000000100000000L
-----------------------------
0x 00000000cafebabeL
If you want to get the correct result 0x1cafebabe, then you need to add "L" after the second array of operations to explicitly consider the long type as positive, at which point the sum extension
The exhibition sign bit is 0:
Java code
- System.out.println (long.tohexstring (0x100000000l + 0xcafebabeL));//1cafebabe
5. Use sign bit extension or 0 to extend Java code when the narrow number type is raised to a wide type
- SYSTEM.OUT.PRINTLN ((int) (char) (byte)-1);//65535
What is the result of 65535 instead of-1?
The symbol extension rule when a narrow integer is converted to a wider integer: If the initial numeric type is signed, then the symbol extension is performed (that is, if the symbol bit
is 1, the extension is 1, if it is zero, the extension is 0), and if it is a char, the 0 extension is performed regardless of what type it will be promoted to.
After understanding the above rules, let's take a look at the puzzle: Because Byte is a signed type, the byte value-1 (binary: 11111111) is raised
When ascending to char, the sign bit extension occurs, and the sign bit is 1, so 8 1 is added, the last is 16 1, and then the promotion from char to int is made by a
The char type is promoted to other types, so the 0 extension instead of the symbol extension results in an int value of 65535.
If you convert a char value C to a wider-width type, only zero is extended, but if you explicitly express the intention of extending with 0, you can consider
Use a bitmask:
Java code
- int i = C & 0xffff;//is essentially equivalent to: int i = C;
If you convert a char value C to a wider-width integer and want to have a symbol extension, first convert char to a short, which
Char last has the same width, but it is signed:
Java code
- int i = (short) C;
If you convert a byte value B to a char, and you do not want a symbolic extension, you must use a bitmask to limit it:
Java code
- char C = (char) (b & 0xff);//char C = (char) b; for signed extension
6. ((byte) 0x90 = = 0x90)?
The answer is no, although the appearance seems to be true, but it is equal to false. In order to compare byte values (byte) 0x90 and int values 0x90,java
promote byte to int by widening the native type, and then compare the two int values. Because Byte is a signed type, this conversion performs the
A symbol extension that promotes a negative byte value to an int value equal to the number (10010000?111111111111111111111111 10010000). In this example, the transformation promotes (byte) 0x90 to an int value of 112, which is not equal to the 0x90 of the int value, or +144.
Workaround: Use a masking code to remove the effect of the symbol extension, thus transforming byte to int.
Java code
- ((Byte) 0x90 & 0xff) = = 0x90
7. Ternary expression (?:) Java code
- char x = ' x ';
- int i = 0;
- System.out.println (True x:0);//X
- System.out.println (false? i:x);//88
Rules for conditional expression result types:
(1) If the second and third operands have the same type, then it is the type of the conditional expression.
(2) If the type of an operation is t,t to represent a byte, short, or char, and the other operand is a literal constant of type int, and
Its value can be expressed in type T, and the type of the conditional expression is T.
(3) Otherwise, the operand type is promoted, and the type of the conditional expression is the type after which the second and third operations are promoted.
Now to use the above rules to solve the puzzle above, the first expression conforms to the second rule: the type of an operand is char, and the other type is literal
An int of type 0, but 0 can be represented as char, so the final return type is the char type, and the second expression conforms to the third rule: because I is an int
Type variable, and x is a char variable, so the X is promoted to type int, so the final result type is int, but if I is defined as final,
The returned result type is char, then the second rule is met, because a variable of the final type replaces the ternary table with literal constant 0 at compile time
Up to the type:
Java code
- final int i = 0;
- System.out.println (false? i:x);//X
In the JDK1.4 version or before the conditional operator?: When the second and continuation three operands are reference types, the conditional operator requires one of them
Must be another subtype, and it is not possible for them to have the same parent class:
Java code
- public class T {
- public static void Main (string[] args) {
- System.out.println (f ());
- }
- public static T F () {
- // !! 1.4 cannot be compiled, but 1.5 can
- // !! return true?new T1 (): New T2 ();
- return true? (T) New T1 (): New T2 ();//T1
- }
- }
- Class T1 extends T {
- Public String toString () {
- return "T1";
- }
- }
- Class T2 extends T {
- Public String toString () {
- return "T2";
- }
- }
In versions 5.0 or later, conditional operators are always legal when the continuation of two and the third operand are reference types. The result type is the two types of the most
Small public super class. Public superclass always exists, because object is a super type for each object type, and the smallest public superclass above is T, so it can be compiled.
Java's often forgotten things