Long class is analyzed from the perspective of JDK source code

survey

The main function of Java's long class is to encapsulate the basic type long and provide some methods to deal with long types, such as long to string conversion methods or string to long conversion methods. Of course, it also includes conversion methods with other types. In addition, there are some bit related operations.

Java long data type

The long data type is a 64 bit signed Java raw data type. Used when the evaluation result of an integer may exceed the range of int data type.

The long data type range is - 9223372036854775808 to 9807 (- 2 ^ 63 to 2 ^ 63-1).

All integers within the range of long data type are called integer face quantities of long type. Integer constants of type long always end in uppercase L or lowercase L.

The following is an example of using an integer face quantity of type long:

This article mainly introduces the relevant content of long class through JDK source code analysis, which can be shared for your reference and learning. I won't say much below. Let's take a look at the detailed introduction together.

Inheritance structure

Main attributes

When type executes toString, the logic is as follows. In fact, the getname function determines its value. Getname obtains the name from the JVM layer through the native method getname0,

Getname0 obtains the corresponding name according to an array, and the JVM can obtain the array subscript of the corresponding type according to the class of the Java layer. For example, if the subscript here is 11, the name is "long".

Longcache inner class

Longcache is an internal class of long. It contains a long array of long possible values. The default range is [- 128127]. It will not cache all possible values like byte class. Because the range of long types is large, it is too expensive to cache them all. Byte types range from - 128 to 127, with a total of 256. Only 256 long objects are instantiated by default. When the value range of long is [- 128127], the corresponding long objects are directly obtained from the cache without re instantiation. These cache values are static and final to avoid repeated instantiation and recycling.

Main methods

Parselong method

The two parselong methods mainly focus on the second. The first parameter is the string to be converted, and the second parameter represents the hexadecimal number. How to better understand this parameter? For example, long Parselong ("100", 10) represents 100 in decimal, so the value is 100, while long Parselong ("100", 2) represents binary 100, so the value is 4. In addition, if long Parselong ("1000000000000000000000", 10) will throw Java Lang.numberformatexception exception.

The logic of this method is to first judge that the string is not empty and the hexadecimal number is in character MIN_ Radix and character MAX_ Between radix, i.e. 2 to 36. Then judge that the length of the input string must be greater than 0, and then process according to whether the first character may be a number or a negative or positive sign. The core processing logic is string to number conversion, and the method of converting n-ary to decimal is basically known to everyone. If 357 is 8-ary, the result will be $3 * 8 ^ 2 + 5 * 8 ^ 1 + 7 * 8 ^ 0 = 239 $. If 357 is decimal, the result will be $3 * 10 ^ 2 + 5 * 10 ^ 1 + 7 * 10 ^ 0 = 357 $. The above conversion method is almost based on this method, but the idea is changed slightly, The methods are $((3 * 8 + 5) * 8 + 7) = 239 $and $((3 * 10 + 5) * 10 + 7) = 357 $respectively. From which we can deduce the rules. Traverse each character of the string from left to right, multiply it by the hexadecimal number, add the next character, then multiply it by the hexadecimal number, add the next character, and repeat until the last character. In addition, another difference is that the above conversions do not use addition, but are all converted to negative numbers for operation. In fact, they can be regarded as equivalent. This is easy to understand, and why they do so should be attributed to the range of long type, because the negative number long MIN_ When value changes to a positive number, it will cause value overflow, so all operations are performed with negative numbers.

Constructor

Contains two constructors, which can pass in long and string types respectively. It is converted by calling the parselong method, so the conversion logic is the same as the parselong method above.

The main task of this method is to put a long value into the char array, for example, 357 into the char array in order. Many skills are used in the processing. The long is divided into the upper 4 bytes and the lower 4 bytes. The while (I > = integer. Max_value) part is to process the upper 4 bytes and process 2 digits each time. There is a special place ((Q < < 6) + (Q < < 5) + (Q < < 2)) that is actually equal to Q * 100 and integer Digittens and integer The function of digitones array has been described in the previous integer article, which is used to obtain ten bits and ten bits.

Next, see how to deal with the lower 4 bytes. It continues to divide the 4 bytes into the upper 2 bytes and the lower 2 bytes. The while (I > = 65536) part is to deal with the upper 2 bytes, and deal with the 2 digits each time. The processing logic is the same as that of the upper 4 bytes.

Let's look at how to deal with the next two low-order bytes. In fact, the essence is the idea of remainder, but some skills are used. For example, (I * 52429) > > > (16 + 3) is actually about equal to I / 10, ((Q < < 3) + (Q < < 1)) is actually equal to Q * 10, and then through integer Get the corresponding characters from the digits array. It can be seen that in low-order processing, it avoids division as much as possible and uses multiplication and shift right instead. It can be seen that division is a more time-consuming operation than multiplication and shift. In addition, it can be seen that multiplication can be realized by shift and addition, and multiplication is not used as much as possible, which also shows that multiplication is more time-consuming than them. The high-order processing does not use shift because it may overflow after multiplication.

ToString method

There are three toString methods in total. One of the two static methods is a non static method. The first toString method is very simple. First, use stringsize to get the number of digits, then getchars to get the char array corresponding to the number, and finally return a string type. The second toString calls the first toString. There's nothing to say. The third toString method takes hexadecimal information, which will be converted into the corresponding hexadecimal string. Everything that is not in the range of 2 to 36 decimal will be processed into 10 decimal. We all know that when converting from decimal to other decimal, we constantly divide the decimal number to get the remainder, and then string the remainder in reverse to get the final result. Therefore, this is actually done here. After obtaining the remainder, we obtain the corresponding characters through the digits array, And here it's in the form of negative numbers.

Valueof method

There are three valueof methods. The core logic is in the first valueof method. Because longcache caches long objects with [- 128127] values, you can directly obtain the corresponding long objects from the array of longcache for those within the range, while those outside the range need to be re instantiated.

Decode method

The main function of the decode method is to convert the decoded string into a long type, such as long The result of decode ("11") is 11; Long. Decode ("0X11") and long The result of decode ("#11") is 17, because the beginning of 0x and # will be processed into hexadecimal; Long. The result of decode ("011") is 9, because the beginning of 0 will be processed into octal.

Xxxvalue method

Methods including shortvalue, intvalue, longvalue, bytevalue, floatvalue and doublevalue are actually converted to corresponding types.

Hashcode method

You can see the int type returned by the hashcode method. First, move the long value unsigned to the right by 32 bits, then XOR with the original value, and finally return the int type value.

Hashcode method

When comparing whether it is the same, first judge whether it is of long type, and then compare the values.

Compare method

If x is less than y, it returns - 1, if equal, it returns 0, otherwise it returns 1.

Unsigned conversion

The tounsignedbiginteger method converts long into BigInteger, mainly BigInteger Valueof is converted. If it is less than 0, it needs to be converted to high 4 bytes and low 4 bytes before conversion.

In the tounsignedstring method, toString is directly used to convert long values greater than 0, while those less than 0 should be processed differently according to different hexadecimals.

Bitcount method

This method is mainly used to calculate the number of 1 in binary numbers. At first glance, it's a little confused. It's all shift, addition and subtraction. First, list the important ones. 0x5555555555555555555555555l is equal to 0101010101010101010101010101010101010101010101010101010101010101, 0x3333333333333l is equal to 001100110011001100110011001100110011001100110011, and 0x0f0f0f0f0f0f0fl is equal to 0000111100111100001111000011110000111100001111000011110000111100001111000011110000111100001111. Its core idea is to count the number of 1s in every two bit group. For example, 10011111 has 1, 1, 2 and 2 1s in every two bits, which is recorded as 01011010, and then calculate the number of 1s in every four bit group, while 01011010 has 2 and 4 1s in every four bits, which is recorded as 00100100, and then 00000110 in every eight bit group, followed by 16 bits, 32 bits and 64 bits. Finally, the sum operation is performed with 0x7F, The number obtained is the number of 1.

Highestonebit method

This method returns the highest 1 in the binary of I, and all other values are 0. For example, when I = 10, the binary is 1010, the highest bit is 1, and the others are 0, which is 1000. If I = 0, 0 is returned. If I is a negative number, it returns - 2147483648, because the highest bit of the negative number must be 1, that is, there are 10000000000. What does this pile of shift operations mean? In fact, it is not difficult to understand that if I is moved to the right by one bit and then operated, the right side of the highest bit 1 will be 1. Then, if I is moved to the right by two bits and then combined or operated, then 1 + 2 = 3 bits on the right will be 1, and then 1 + 2 + 4 = 7 bits will be 1 until 1 + 2 + 4 + 8 + 16 + 32 = 63 is 1. Finally, I - (I > > > 1) will naturally get the final result.

Lowestonebit method

Corresponding to the highestonebit method, lowestonebit obtains the lowest value of 1 and all other values of 0. This operation is relatively simple. Take the negative number first. In this process, you need to take the inverse code of the positive number I, and then add 1. The result and I are and operated. It is just the lowest 1 and the other values are 0.

Numberofleadingzeros method

This method returns the number of zeros in the binary of I from scratch. If I is 0, there are 64 zeros. The processing here actually reflects the idea of binary search. First, see whether the high 32 bits are 0. If yes, there are at least 32 zeros. Otherwise, move 16 bits to the left and continue to judge. Then move 24 bits to the right to see whether it is 0. If yes, there are at least 16 + 8 = 24 zeros, and so on until the final result is obtained.

Numberoftrailingzeros method

Corresponding to the previous numberofleadingzeros method, this method returns the number of zeros from the tail of the binary of I. Its idea is similar to the previous one. It is also based on the idea of binary search, and the detailed steps will not be repeated.

Reverse method

This method is to invert I, that is, the first bit is swapped with the 64th bit, the second bit is swapped with the 63rd bit, and so on. Its core idea is to exchange two adjacent bits first, such as 10100111 for 01011011, then exchange four adjacent bits, which is 10101101, then exchange eight adjacent bits, finally exchange 32 bits in the middle of 64 bits, and then exchange the highest 16 bits with the lowest 16 bits.

Tohexstring and tooctalstring methods

These methods are similar. Put them together. Look at the name to know the string converted to binary, octal and hexadecimal. You can see that the tounsignedstring0 method is called indirectly. This method will first calculate the number of characters required to convert to the corresponding hexadecimal, and then fill the character array through the formatunsignedint method. What this method does is to use the conversion method between hexadecimals to obtain the corresponding characters.

summary

The above is the whole content of this article. I hope the content of this article has a certain reference value for your study or work. If you have any questions, you can leave a message. Thank you for your support for programming tips.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>