The first chapter Java data type conversion

Starting from this chapter, we will analyze the knowledge points from the java basic module. Including basic data types, packaging classes, String, IO, exceptions, threads, collections, etc. analysis or original code analysis.
I plan to start with this article and gradually study the basic knowledge points of java. I am also constantly learning. If there is an incorrect description in the article, I hope that all the gods can be more accurate.
JAVA type conversion is something that is often encountered in coding. I think if you don't understand the principle in depth, one day you will fall into a big hole. So this chapter will introduce the type conversion and detailed analysis of different data types in java. If I can help you, I hope I can like it.

Knowledge structure diagram of this chapter:
Insert picture description here

Concept introduction

所谓类型转换,即对数据的操作。java的数据类型分为两种;

1. Basic data types

Basic data types are divided into numeric types and non-numeric types. There are 8 kinds in total;

Numerical type
byte (1 byte)
short (2 bytes)
int (4 bytes)
long (8 bytes)
float (4 bytes)
double (8 bytes)

Non-numeric type
char (2 bytes)
boolean (not sure)

2. Reference data types

Reference data type refers to any reference variable that points to an object in the heap, which is a reference data type. For example, Book book = new Book(); book is a reference data type.

3. Type conversion

First, let's analyze the type of forced conversion, the so-called forced type conversion, strong: mandatory, forced.
My own understanding is that large space bytes are converted to small space bytes. For example, when a byte variable is declared, 1 byte will be allocated, and an int variable will be allocated 4 bytes. If int is converted to byte, it is a forced type conversion. In the same way, turning long to int is also the behavior of turning a large space into a small space.
Forced type conversion can easily cause data overflow, the so-called overflow. We can compare 8 data types to 8 buckets of different sizes.

When the big bucket pours water into the small bucket, (Although the picture is a bit ugly, the picture is rough and not rough)
Regardless of whether the small bucket can be installed, it is called forced type conversion (display type conversion) .
On the contrary, the water from the small bucket can be filled into the big bucket. Known as implicit type conversion;

The basic concepts and the principle of type conversion are probably as mentioned above. Let's study the implementation details in java.


1. Basic data types

1. Integer

	数值型有6种:
	byte (1字节)   		short(2字节)       int(4字节)
	long(8字节)    	float(4字节)       double(8字节)

(1) Forced type conversion

The following will be reduced to the calculation of the original code, one's complement, and the complement of the memory, so a few basic knowledge points will be emphasized at the beginning.

1. The data in the memory is in the form of complement;
2. A data in the memory is represented by (sign bit + true value). The highest bit represents the sign bit, 0 bit is positive, 1 is negative.
4. The original code of the positive number = the inverse code = the complement code; when the original code, the inverse code, and the complement of the negative number are calculated, the sign bit of the highest bit is not in the calculation.
3. In the shift operation, when shifting to the right, the high digit of the positive number is insufficient and filled with 0, and the high digit of the negative number is insufficient, filled with 1; when shifting to the left, the low digit is insufficient, and all filled with 0
.

Example demonstration

int i = 200;
byte b = (byte) i;
System.out.println(b);
结果:-56;

Let's analyze the process of this example. This example is a cast from int to byte. According to the above basic knowledge, we know that the int type will allocate 4 bytes, and the byte type will allocate 1 byte. So how is it calculated internally?

  • Solution: The
    variable i will be allocated 4 bytes, that is, 32 bits. We can imagine it as a bucket with a capacity of 32.

    The value 200 will be compiled into binary 11001000; we can think of it as the volume of water. The value is positive, so the highest bit is 0;
    then the original code of this value is expressed as:
    0000 0000 0000 0000 0000 0000 1100 1000 (32 bits in total)
    Since the memory is the complement code stored, the original code of the positive number is calculated according to the calculation rule. Code = inverse code = complement code;
    the complement code of the value 200 is:
    0000 0000 0000 0000 0000 0000 1100 1000 (32 bits in total),
    so the complement code should be placed in 32 spaces. Then to analyze the variable b;

    The variable b will be allocated one byte, that is, 8 bits, which is equivalent to a bucket with a capacity of 8.

    Now we need to use a bucket with a capacity of 8 to hold the value of 200, that is, the 200 value of the int type, which is the complement of the 32-bit memory above;
    because the complement has a 32-bit length, 32 spaces are needed, while the byte is only 8. A grid can only hold 8 digits, so 24 digits will overflow.
    The overflow rule is high overflow. Only the lower 8 bits can be installed.
    So in fact, the complement of the value stored in the variable b is 1100 1000;

    Observe that the most significant bit is 1 through the complement code, so the number is negative. But the specific value should be judged according to the original code.
    From the inverse code = complement code-1; the inverse code can be obtained:
    1 100 0111 ;(Don’t do the subtraction wrong, I just counted it wrong)
    From the original code = the inverse code, the original code can be obtained:
    1 011 1000 ; the
    highest bit is 1, which is also the first bit on the left, and the sign is negative.
    The true value is 011 1000, and the result is 56 when converted to decimal;
    therefore, the final result is -56;

Example demonstration

int = -40000;
short s = (short ) t;
System.out.println(s);
结果:保密;

Let's calculate it according to the above method first. The data type of short is 2 bytes, that is, 16 bits. Excluding 1 sign bit, the remaining 15 positions can store values. So the value of short ranges from -2 to the 15th power to +2 to the 15th power; that is, -32767 to 32767.
If you want to store the -40000 value of the int type in the short, -40000 <-32767. So it will definitely overflow. Let's calculate the result.

If the variable t is an int type, 32 spaces will be allocated, the highest bit is negative, and the binary representation of -40000 is 1001 1100 0100 0000;
so the
original memory code of the variable t is: 1 000 0000 0000 0000 1001 1100 0100 0000;
memory The inverse code is: 1 111 1111 1111 1111 0110 0011 1011 1111; the
complement of memory is: 1 111 1111 1111 1111 0110 0011 1100 0000;

Short now has only 16 grids, so the complement that can be installed is: 0110 0011 1100 0000; the
highest bit is 0, so the value is positive. Therefore, the complement of a positive number = the original code, so the original code of the number is: 0110 0011 1100 0000;
converted to decimal is 25536,
so the final result is positive 25536
Conclusion: When the actual water in the big bucket exceeds the capacity of the small bucket, it will overflow by force. Its value changes.

So if the water in the big bucket can be contained in the small bucket, what will be the result?

Example demonstration

short s= 89;
byte b = (byte) s;
System.out.println(b);
结果:保密;

Similarly, install the above calculation method, let's calculate it.
First, 16 grids are allocated to the short type s variable, the highest bit is filled with symbols, and the remaining 15 bits are filled with values.
Binary bits of 89: 1011001
So the complement code in the memory of the variable s is: 0000 0000 0101 1001 The
byte type variable b has only 8 grids, so the complement code it contains is: 0101 1001 The
highest bit of the observation is 0 through the complement code. Its value is positive. The complement of a positive number = the original code; so the original code is also 0101 1001, and converted to decimal is 89.
Conclusion: When the actual water in the big bucket does not exceed the capacity of the small bucket, its value remains unchanged.

(2) Implicit type conversion

The principle is the same as that of forced type conversion. The only difference is that one is to put a big bucket into a small bucket, and the other is to pour a small bucket into a big bucket. The big bucket can surely fit, unless the big bucket has a hole.
So no matter which bucket is poured into, its value will not change, it is the same. The calculation method is the same as above.
Let's demonstrate it again:

Example demonstration

byte b= -89;
short s = b;
System.out.println(s);
结果:保密;

First of all, the original code of -89 is: 1101 1001;
its inverse code is: 1010 0110;
so the complement of b is 1010 0111; now you need to load -89 into variable s, variable s of
short type has 16 grids, After loading the value in variable b into s,
its original code is: 1 000 0000 1101 1001 and
its complement is: 1 111 1111 1110 0111 .
I have also thought about it here, why shouldn’t the complement of variable b be directly loaded into the grid of variable s and become
0 000 0000 1010 0111? Instead, it becomes
1 000 0000 0010 0111. Why is the sign bit shifted?
I am also puzzled. But we can verify by shift operation, what exactly is its complement.
If it is 0 000 0000 1010 0111, the highest bit is 0, this value must be positive, and
the complement of the true value becomes 1010 0111. So there must be some underlying principles that I don't know. But what is certain is that the value of implicit type conversion will definitely not change.

(3) Type conversion in mixed operations

Example demonstration

short s = 1;
int  i =130;
byte g = (byte )(s+i);
System.out.println(g);
结果:-125

It should be noted here that the default data type in Java is int. If you use other types to receive it, you must perform type conversion, but some are implicit type conversions and are not displayed.
Such as: long n = 130; is actually equivalent to long n = (long) 130;
where 130 is the int type.
Therefore, let's analyze the above example. The first two sentences are definitions, and the focus is on the last sentence;

byte  g = (byte )(s+i);

Here s is short, i is int, s+i will be converted to int by default, because the default data type of java is int.
Therefore, the value after s + i is: 131 of type int. If the numeric types on both sides do not match, the compiler will report an error.
You may ask this question:

byte g = (byte)s+(byte)i;

Is it possible to write in this way, so that its value will be converted to int type 131 by default after
writing. So it can only be written like this:

byte g = (byte )(s+i);

First, s+i becomes int type 131, and then it is forcibly converted from int to byte.
Example demonstration

byte b = 1;
b = b +1;
System.out.println(b);
结果:报错,b+1后变为int类型,不能直接转为byte。

byte b = 1;
b += 1;
System.out.println(b);
结果:2      += 除了可以实现增加,还会执行强转。因此已经由int转为了byte。

Example demonstration

	short s = 1;
    int i =2147483647;
    long t = s+i;
    System.out.println(t);
    结果:-2147483648,那为什么不是2147483648?

The numeric type of int is -2^31 to 2^31, that is, -2147483648 to 2147483647. Why is the result here -2147483648. Let's deduce it.
At the beginning of the deduction, I have to ask a question, the following two int type original code values ​​represent the two decimal numbers.

1000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000 

Does it look like positive 0 and negative 0? In fact,
it is not. Among them,
1000 0000 0000 0000 0000 0000 0000 0000 represents the minimum value of the negative range, which is -2147483648.
0000 0000 0000 0000 0000 0000 0000 0000 represents the minimum value of the positive number range, that is, 0.
We can deduce:

2147483648的二进制原码:1000 0000 0000 0000 0000 0000 0000 0000
正数的原码= 反码  1000 0000 0000 0000 0000 0000 0000 0000,在int类中,这个补码表示一个负数,
所以其值为-2147483648。
这也是为什么计算机发展过程中,为什么引入了补码的原因,
就是为了解决正0 和负0 的表达。所以规定了  补码=原码取反+1  的公式,只有这样才能表达出所有数字。

Going back to the example above, int i = 2147483647;
its original code=complement code=0111 1111 1111 1111 1111 1111 1111 1111
this complement code+1=1000 0000 0000 0000 0000 0000 0000 0000
up and down, that is, 2147483647 + (-2147483648 )= -1, complement code:
1111 1111 1111 1111 1111 1111 1111 1111
-1+1, it becomes 1 0000 0000 0000 0000 0000 0000 0000 0000, but int can only hold 32 bits, so the high bit overflow and the remaining complement code is
0000 0000 0000 0000 0000 0000 0000 0000
is 0 in decimal.

2. Floating point

There are two floating-point types, float (single precision) and double (double precision). Floating-point uses scientific notation in the computer. For infinite decimals, the longer the position, the higher the accuracy. However, different languages ​​have different settings based on the scope of use and computer cost.
Float in Java occupies 4 bytes, a total of 32 bits of memory space.
double occupies 8 bytes, a total of 64 bits of memory space.
Decimals in java default to double type. If you need to convert to float, it is called forced type conversion. You need to add f after it or float before it.

float h = 1.0;     //结果 编译错误
float f = 1.0f;    // 结果  1.0
double d = 1.0;    //结果 1.0

(1) Type conversion between floating points

The floating point has a decimal point, and the position of the decimal point for different decimals is different in the fixed 32-bit or 64-bit space. According to the four rules of mathematics, you need to align the decimal point before adding or reducing the number. Therefore, in order to align the decimals, the addition and subtraction between different decimals will inevitably cause a decimal to move to the left or right. The movement will cause the data to overflow, and the result will naturally change, which is the loss of precision. This is the reason why floating-point types are not used for calculations between decimals.
For example: 1.2 + 1.112 =? ; Normal mathematical operations should be equal to 2.312, but in a computer, the result is

结果: 2.3120000000000003

Because double is a double-precision type, and float is a single-precision type. When double is converted to a float, for a decimal with a longer precision, the precision will inevitably be lost, which is a forced type conversion, otherwise it is an implicit type conversion. The details of its changes will not be studied here.

3. Type conversion between integer and floating point

Example demonstration

int  t = 1.234;
system.out.print(t)
// 结果: 1

.1.234 is a double type. After being converted to an integer type, only the integer part of its original value can be retained.

Example demonstration

double  d = 1;
system.out.print(d);
// 结果: 1.0

After the integer is converted to floating point, it becomes a floating point, followed by a decimal number.

Example demonstration

当整型 与 浮点型进行加减运算时的类型变化;
float a = 1 + 1.2f;    // 结果: 2.2  
double b = 1 + 1.2;    // 结果: 2.2
int t= (int)(1+1.2f)    

Two, non-numerical

1. Character type

Character type refers to the basic data type char. Since char is encoded in unicode, unicode can be understood as a very thick dictionary.

历史:
	计算机发明之初,美国人的只需要128个字符,即ASCII码,ASCII码是一本很薄很基础字典,
美国人用它就可以表示它的所有需求。后来随着计算机的普及,有些国家所需要表达的字符个数远远超过了128个,并且
不同国家有不同国家的字符。于是美国人又在ASCII码的基础上开始扩展,将所有国家的所有符号用全部统一起来做成了
一本厚字典。也就是Unicode码,它是采用16进制表示。那Unicode 和 UTF-8、UTF-16、UTF-32有什么关系呢?
	上述三种UTF-8、UTF-16、UTF-32是实现Unicode 转换为二进制所采用的的方式,因为现在使用了Unicode这个
字典,如果采用定长字节来表示,最多需要使用4个字节来表示,然后美国人或者有些国家用不着那么长的空间,
一个英文文本明明只需要1kB,结果现在变成了4kB。造成了极大的空间浪费。于是UTF-8就是不定长的编码方式,只需要
一个字节表示的字符,就只开辟一个字节空间,如果需要两个字节,则开辟两个字节空间。所以优秀的 UTF-8 的编码
方式被广泛应用于计算机领域。

Char occupies two bytes and can store 65535 characters. If this limit is exceeded, it will cause overflow. for example

int a = 65 + 0;
char c = (char) a;
System.out.println( c );
结果:A

Unicode is extended on the basis of the ASCII code, so the first 128 bits are still the same as the ASCII code. Here we use the data before 128 bits as an example for convenience. Therefore, we can calculate that
the original code of the value 65 is 0000 0000 0000 0000 0000 0000 0100 0001, and the complement is also this code;
char can hold 16 binary, so the complement in the char memory is actually 0000 0000 0100 0001 , The code is parsed against ASCII, and the character is A.

如果
int a = 65 + 65534;
char c = (char) a;
System.out.println( c );
结果: ?

How much should the result be? Let's calculate it.
Int type a = 65599, original code = complement code = 0000 0000 0000 0001 0000 0000 0011 1111;
char occupies 2 bytes, get the low sixteen bits of the complement code, so the actual complement code of its memory is
0000 0000 0011
The value of 1111 is positive, so the original code is also 0000 0000 0011 1111. Is this a character by ASCII code comparison? .

如果
int b = '中';
System.out.println(b);
结果:20013   

Here is the Chinese character "中" as an example. This code is actually an implicit type conversion, because char is 2 bytes and int is 4 bytes, so the conversion of char to int is an implicit type conversion. We can check Baidu:

You can see that the binary code of the Chinese character is:
1110 0100 1011 1000 1010 1101
Chinese character occupies three bytes, why can char be stored, because the hexadecimal representation of the Unicode code stored in char Point,
let’s check the Unicode code point of the Chinese character.

We found that the code point of the Chinese character is \u4e2d, \u, which means unsigned, meaning unsigned. The hexadecimal number is 4e2d.
The hexadecimal 4e2d converted to binary is:
0100 1110 0010 1101
Therefore, the actual original code of the middle word stored in char is 0100 1110 0010 1101 instead of the three-byte binary code found above.
Now convert char to int number, the original code is:
0000 0000 0000 0100 1110 0010 1101.
After conversion, the output decimal result is: 20013

Three, Boolean-type conversion

Boolean types cannot be converted to and from other basic data types, and bitwise operations cannot be used. So I gave up the research.

Four, reference type-type conversion

Reference data types are reference variables of all types except basic data types.
In memory, a reference variable is also a piece of data, but its stored value is an address, which points to the real value of the variable. Therefore, the reference variable is called a reference data type.
Since the reference data type stores an address, there are several situations to analyze.

(1) This reference points to an empty object

int a = null;
编译错误

a This variable is a basic data type, and the basic data type cannot accept a null object, so a compilation error occurs.

Integer g = null;

g This variable is an object reference, null can be forced to any object. Because the object can accept null.

(2) This reference points to another object

Example demonstration: non-parent-child relationship

	Student  a = new Student;
	Teacher t = (Teacher) a;

Here, we need to convert Student to Teacher object. Obviously due to the type mismatch, the compiler can't pass, so the compiler will report an error.

Example demonstration: parent-child relationship

Object ob = new Object();
Teacher t = (Teacher)ob;   父转为子(强制转换)也称为向下转型
Object  et = Teacher ;  子 转为 父(隐式转换)也称为向上转型

Object is the root of everything, just like the Tai Chi of the universe. Tai Chi produces two instruments, two instruments produce four images, and four images produce gossip. Everything in the world is derived from Object. So it is the parent class of all objects.
Two words appear in the conversion here. One is the upward transformation and the other is the downward transformation. Why is downward transition called forced transition instead of upward transition?
The previous basic data type is defined as forced conversion as the transfer of large space into small space, causing data overflow and risk of data error. The same is true here.
In Xiao Yuan’s understanding, a variable is a value, and its value points to an object in the heap. The type of the declared variable is the mapping of the objects in the heap. Look at the picture:

an object has its own properties and behavior methods. For the parent class, the child class is an extension of the properties and behavior methods of the parent class. So in the same way, when declaring the variable t of the Teacher class, the default indicates that the variable t will point to an instance object of Teacher, but now it is necessary to change this point to the parent object Object.

This will involve the risk of data errors. If all the methods called by the variable t, Object has all, and all of its methods can be called successfully, then there is no risk of data error in the variable t of the Teacher type, and the coercion of the parent-child type is safe. Conversely, if the Object has only some methods in the variable t method, then an error will occur when calling methods that the Teahcer object has but the Object object does not have.

Happy moment

小王是工程局的一名干事,有一天领导交给他一个工程让他去负责办理,三个月后验收。
小王心里高兴得不了,这项工程实际上一个月就可以完成了,于是他开始想剩下的两个月怎么办。
如果早早把工程就办完了,那就得继续干下个工程,即得不到多余的报酬,也浪费了这两个月假期。
于是小王带着一家人去了国外旅游,计划好时间。到时候回来开工。
谁曾想,返回的途中遇到了意料之外的麻烦,匆匆赶回国后只剩下15天时间了。但是还有领导交给他
的一个月工程没干。无奈之下,小王只有昼夜加班,只干完了主体工程。
...
到了交接那天,领导拿着图纸来查看工程进度。发现跟图纸不匹配,工程主体缺这儿缺那儿的,领导一肚子火气。
于是小王遭到了惩罚,被领导炒了鱿鱼。
跟上述对象强制转换一样。引用变量 t 原以为可以调用Teacher 类型的所有方法,结果中途被小王换成了
对象Object ,所以在调用某些方法时,程序就报错了。

Guess you like

Origin blog.csdn.net/weixin_43901067/article/details/103766581