【Java】数据类型

数据类型

在这里插入图片描述

Java是一种强类型语言。这就意味着必须为每一个变量声明一种类型。在Java中,一共有8种(primitive type)基本类型,其中有4种整型(byte、short、int、long)、2种浮点类型(float、double)、1种用于表示Unicode编码的字符单元的字符类型char和1种用于表示真值的boolean类型。

基本数据类型相关(8个):byte、short、int、long、float、double、char、boolean 。

8位整数类型、16位整数类型、32位整数类型、64位长整数类型、32位单精度浮点数类型、64位双精度浮点数类型、 布尔类型。

1 、Java数据类型的分类

1、基本数据类型

​ 8种:整型系列(byte,short,int,long)、浮点型(float,double)、单字符型(char)、布尔型(boolean)。

byte(1个字节)short(2个字节)int(4个字节,整数的默认类型)long(8个字节)
字节byte:1个字节,-128~127
短整型short:2个字节,-32768~32767。

浮点型:float(4个字节)double(8个字节,小数的默认类型)。

字符型:char(2个字节)。

布尔型:boolean(只有两个值true和false)。

2、引用数据类型

​ 类、接口、数组、枚举…

类(class)/接口(interface)eg:String字符串,数组([])。泛型(<>)。

基本数据类型:整型、浮点型、字符型、布尔型

引用数据类型: 类、接口、数组、枚举

2、 Java的基本数据类型

1、整型系列

(1)byte:字节类型

占内存:1个字节

存储范围:-128~127

(2)short:短整型类型

占内存:2个字节

存储范围:-32768~32767

(3)int:整型

占内存:4个字节

存储范围:-2的31次方 ~ 2的31次方-1

(4)long:整型

占内存:8个字节

存储范围:-2的63次方 ~ 2的63次方-1

注意:如果要表示某个常量数字它是long类型,那么需要在数字后面加L

2、浮点型系列(小数)

(1)float:单精度浮点型

占内存:4个字节

精度:科学记数法的小数点后6~7位

注意:如果要表示某个常量数字是float类型,那么需要在数字后面加F或f

(2)double:双精度浮点型

占内存:8个字节

精度:科学记数法的小数点后15~16位

3、单字符类型

char:字符类型

占内存:2个字节

Java中使用的字符集:Unicode编码集

字符的三种表示方式:

(1)‘一个字符’

例如:‘A’,‘0’,‘尚’

(2)转义字符

\n:换行
\r:回车
\t:Tab键
\\:\
\":”
\':
\b:删除键Backspace

(3)\u字符的Unicode编码值的十六进制型

例如:\u5c1a代表’尚’

4、布尔类型

boolean:只能存储true或false

5、注意

  1. Java的整型常量默认为 int 型,如果想要表示某个整数值是long型时,需要在值后面加L或l ,1与l分不清,一般是使用L来表示的 eg: long a = 1L;。java程序中变量常声明为int型,除非不足以表示大数,才使用long。经常使用int呀 整型数据。
  2. Java 的浮点型常量默认为double型,声明float型常量,须后加‘f’或‘F’ eg:float f=3.14F;。float可以保证十进制科学计数法小数点后6位有效精度和第7位的部分精度。double可以保证十进制科学计数法小数点后15位有效精度和第16位的部分精度。
  3. 字符型的值必须使用单引号,只能而且必须存储单个字符,不能是空单引号。例如:’a’、’\n’、’\u5c1a’。字符型使用Unicode编码(ASCII,特殊字符,中文、日文、韩文…)
  4. String是引用数据类型,String的常量值必须使用双引号。单独的双引号也是一个字符串值。eg:String name="小蚂蚁";

3、了解 进制

计算机中任何的计算和存储都是以二进制方式实现的 0、1

位(bit) — 是计算机中最小的存储单位

字节(byte) — 计算机中基本的存储单元

1byte = 8bits、1KB = 1024Byte、1MB = 1024KB、1GB = 1024MB、1T = 1024GB

1、进制的分类:

(1)十进制

​ 数字组成:0-9

​ 进位规则:逢十进一

(2)二进制

​ 数字组成:0-1

​ 进位规则:逢二进一

(3)八进制

​ 数字组成:0-7

​ 进位规则:逢八进一

(4)十六进制

​ 数字组成:0-9,af(或AF)

​ 进位规则:逢十六进一

对于整数,有四种表示方式:

  • 二进制:0,1 ,满2进1.以0b或0B开头(字母B大小写均可)。
  • 十进制:0-9 ,满10进1.
  • 八进制:0-7 ,满8进1.八进制数被冠以0来表示。
  • 十六进制:0-9及A-F,满16进1,十六进制数被冠以0X来表示(字母X大小写均可)
    如: 0x3f20(十六进制) 0732 (八进制)

2、请分别用四种类型的进制来表示10,并输出它的结果:(了解)

(1)十进制:正常表示

System.out.println(10);

(2)二进制:0b或0B开头

System.out.println(0B10);

(3)八进制:0开头

System.out.println(010);

(4)十六进制:0x或0X开头

System.out.println(0X10);

class Test01_JinZhi{
    public static void main(String[] args){
        System.out.println(10);//十进制,正常写
        System.out.println(0B10);//二进制,在数字前面加0B或0b
        System.out.println(0b10);//二进制,在数字前面加0B或0b
        System.out.println(010);//八进制,在数字前面加0
        System.out.println(0X10);//十六进制,在数字前面加0X或0x
        System.out.println(0x0f);//15
    }
}

3、为什么byte是-128~127?(理解)

1个字节:8位

0000 0001 ~ 0111 111 ==> 1~127

1000 0001 ~ 1111 1111 ==> -127 ~ -1

0000 0000 ==>0

1000 0000 ==> -128(特殊规定)

*解释:*计算机数据的存储(了解)

计算机数据的存储使用二进制补码形式存储,并且最高位是符号位,1是负数,0是正数。

规定:正数的补码与反码、原码一样,称为三码合一;

负数的补码与反码、原码不一样:

负数的原码:把十进制转为二进制,然后最高位设置为1

负数的反码:在原码的基础上,最高位不变,其余位取反(0变1,1变0)

负数的补码:反码+1

例如:byte类型(1个字节,8位)

25 ==> 原码 0001 1001 ==> 反码 0001 1001 -->补码 0001 1001

-25 ==>原码 1001 1001 ==> 反码1110 0110 ==>补码 1110 0111

底层是用加法代替减法:-128==》-127-1==》-127+(-1)

​ -127- -1 ==> -127 + 1

4、二进制与十进制之间的转换

二进制转成十进制 乘以2的幂数

十进制转成二进制 除以2取余数

在这里插入图片描述

5、二进制 八进制 十六进制互转

二进制转八进制:三位一组,算出这三位对应的十进制值,然后挨个连接上即可

二进制转十六进制:四位一组,算出这四位对应的十进制值,然后挨个连接上即可

在这里插入图片描述

八进制转二进制:把每个位置上的数字当做10进制的数,转成三位的二进制,然后挨个拼接上

十六进制转二进制:把每个位置上的数字当做10进制的数,转成四位的二进制,然后挨个拼接上

在这里插入图片描述

6、十进制与八进制或十进制与十六进制之间的转换,建议通过二进制过渡一下

在这里插入图片描述

7、原码、反码、补码

所有数字在计算机底层都以二进制形式存在。一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1。
Java整数常量默认是int类型,当用二进制定义整数时,其第32位是符号位;当是long类型时,二进制默认占64位,第64位是符号位。

因为机器数是带符号的,因此机器数与一个数的“二进制值”还是有区别的。
计算机以补码的形式保存所有的整数。
正数的原码、反码、补码都相同
负数的补码是其反码加1。
1.原码
原码即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:

+1 原码0000 0001

-1 原码1000 0001

​ 2.反码

正数的反码是其本身

负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.

+1 原码 0000 0001 反码 0000 0001

-1 原码 1000 0001 反码 1111 1110

​ 3.补码

正数的补码就是其本身

负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

+1 原码 0000 0001 反码 0000 0001 补码 0000 0001

-1 原码 1000 0001 反码 1111 1110 补码 1111 1111

为什么要使用原码、反码、补码表示形式呢?
计算机辨别"符号位"显然会让计算机的基础电路设计变得十分复杂! 于是人们想出了将符号位也参与运算的方法. 我们知道, 根据运算法则减去一个正数等于加上一个负数, 即: 1-1 = 1 + (-1) = 0 , 所以机器可以只有加法而没有减法, 这样计算机运算的设计就更简单了.

0000 0000:0

0000 0001 ~ 0111 1111 : 1~ 127

1000 0001 ~ 1111 1111 : -127 ~ -1

1000 0000:-128

(-127) - (1) = -128

(1000 0001 - (0000 0001)= (1000 0000)

在这里插入图片描述
特殊值: -1-127的结果应该是-128, 在用补码运算的结果中, [1000 0000]补 就应该是-128.

但是此时-128,如果用补码到反码,再到原码去计算是不对的,所以**-128是个特殊值,记住它**

8、疑惑解答?

(1)为什么float(4个字节)比long(8个字节)的存储范围大?

(2)为什么double(8个字节)比float(4个字节)精度范围大?

因为float、double底层也是二进制,先把小数转为二进制,然后把二进制表示为科学记数法,然后只保存:

(1)符号位(2)指数位(3)尾数位 网上搜索float型和double型数据的存储方式吧

4、 基本数据类型的转换

1、自动类型转换(自动升级):小容量转为大容量(系统自动完成)

  • byte,short,char三者之间不进行运算,若运算都将自动升级为int再做运算

  • boolean不与其他任意数据类型转换

  • 任何数据类型与String之间使用“+”运算符都将自动“连接”成String类型

    拼接

(1)当把存储范围小的值(常量值、变量的值、表达式计算的结果值)赋值给了存储范围大的变量时,

byte->short->int->long->float->double

​ char->

int i = 'A';//char自动升级为int
double d = 10;//int自动升级为double

(2)当存储范围小的数据类型与存储范围大的数据类型一起混合运算时,会按照其中最大的类型运算

int i = 1;
byte b = 1;
double d = 1.0;

double sum = i + b + d;//混合运算,升级为double

(3)当byte,short,char数据类型进行算术运算时,按照int类型处理

byte b1 = 1;
byte b2 = 2;
byte b3 = (byte)(b1 + b2);//b1 + b2自动升级为int

char c1 = '0';
char c2 = 'A';
System.out.println(c1 + c2);//113 48

(4)boolean类型不参与

2、强制类型转换

大容量转小容量,需要使用强制符(),结果可能损失精度或溢出

(1)当把存储范围大的值(常量值、变量的值、表达式计算的结果值)赋值给了存储范围小的变量时,需要强制类型转换

double->float->long->int->short->byte

​ ->char

提示:有风险,可能会损失精度或溢出

double d = 1.2;
int num = (int)d;//损失精度

int i = 200;
byte b = (byte)i;//溢出

(2)boolean类型不参与

(3)当某个值想要提升数据类型时,也可以使用强制类型转换

int i = 1;
int j = 2;
double shang = (double)i/j;

提示:这个情况的强制类型转换是没有风险的。

byte,short,char之间是互不转换的,包括byte+byte等运算也会变成int

boolean和谁都不转

String类型的数据与任意类型的数据“+”拼接后结果都是String字符串

5、 特殊的数据类型转换

1、任意数据类型的数据与String类型进行“+”运算时,结果一定是String类型

System.out.println("" + 1 + 2);//12

2、但是String类型不能通过强制类型()转换,转为其他的类型

String str = "123";
int num = (int)str;//错误的

6、code

基本数据类型

/*
Java强类型  非常非常重要
Java中的数据类型:
(1)基本数据类型(8种)
(2)引用数据类型
String是引用数据类型

一、基本数据类型
1、整型系列
byte: 字节类型 范围:-128~127
	1个字节  8个位
short:短整型
	2个字节  范围:-32768~32767
int:整型
	4个字节  范围:....
long:长整型
	8个字节
	说明:对于long类型的常量,需要加大写L(建议用大写)或小写l

2、小数类型,浮点型系列
float:
	单精度浮点型,4个字节,
	大概的精度范围是,把小数用科学记数法表示后,小数点后6~7位
	说明:float类型的常量,需要在数字后面加F或f
double:双精度浮点型,8个字节
	大概的精度范围是,把小数用科学记数法表示后,小数点后15~16位

L , F ,

3、字符类型
char:单字符类型,2个字节,可以表示汉字
	在Java中是使用Unicode编码表表示。(兼容ASCII码)
	每一个字符都有一个唯一的Unicode编码值。
	例如:
		数字0,Unicode编码值是48
		数字1,Unicode编码值是49
		...
		字母A,Unicode编码值是65
		字母B,Unicode编码值是66
		...
		字母a,Unicode编码值是97
		字母b,Unicode编码值是98
		...
如何表示char类型的字符常量呢?
(1)'一个字符',例如:'女','A'
(2)'转义字符',例如:'\n'(换行),'\t'(制表位Tab键),
					'\\'(斜杠),'\"'(双引号),'\''(单引号),
					'\b'(删除键Backspace),'\r'(回车键)
(3)'斜杠u字符的Unicode编码值的十六进制形式'

4、布尔类型
boolean:只能存两个值之一:true,false
一般boolean的值用于条件判断


计算机表示数据用二进制表示,即0和1
那么一位0或1,我们用bit(位),最小单位
计算机中最基本的单位用的byte字节,
1字节 = 8位
1KB = 1024B
1MB = 1024KB
1GB = 1024MB
1TB = 1024GB
...

扩展:
	硬件厂商存储单位用1000进位,不是1024.
	带宽  100Mb,b = bit
    100M  12.5MB/s Mb/s  ???
*/
class TestType{
    public static void main(String[] args){
        boolean marry = false;
        if(marry){//marry中的值为true,就表示条件成立
            System.out.println("已婚");
        }else{
            System.out.println("未婚");
        }
        System.out.println("--------------------------");

        byte b = 127;
//        byte b = 129; //不兼容的类型 从int转换到byte可能会有损sun失
        long tel = 18201583096L;

        float f = 1.2F;

        char shuang = '"';//这样可以,表示单个字符
        System.out.println(shuang);
        System.out.println("渐若窥宏大说:\"今天天气真好\"");//这里要输出双引号,需要转义

        char shang = '\u5c1a';
        System.out.println(shang);
    }
}

进制

/*
进制:(了解)
Java
十六进制 0x0f 0X0f  表示十进制15
八进制 017  15
二进制 0b1111 0B1111
1、进制的分类
十进制:
	数字范围:0-9
	进位规则:逢十进一
二进制:
	数字范围:0-1
	进位规则:逢二进一
八进制:
	数字范围:0-7
	进位规则:逢八进一
十六进制:
	数字范围:0-9、A-F(或者a-f)
	进位规则:逢十六进一
8对7说我溢出了 16对15我要进位了 2对1说嗯嗯
2 8 16 10

		十进制	二进制	八进制	十六进制
0		0		0		0		0
1		1		1		1		1
2		2		10		2		2
3		3		11		3		3
4		4		100		4		4
5		5		101		5		5
6		6		110		6		6
7		7		111		7		7
8		8		1000	10		8
9		9		1001	11		9
10		10		1010	12		A
11		11		1011	13		B
12		12		1100	14		C
13		13		1101	15		D
14		14		1110	16		E
15		15		1111	17		F
16		16		10000	20		10
。。。。

25		25		11001

本质上,就是生活中的十进制,和计算机世界中的二进制
因为在计算机中二进制数字太长了,在代码中去表示二进制很繁琐,
那么引入了八进制和十六进制,为了快速和简短的表示二进制
为了快速和简短的表示二进制
(1)十进制-->二进制
(2)二进制-->八进制
把二进制从最右边开始,三位一组
(3)二进制-->十六进制
把二进制从最右边开始,四位一组

2、在程序中如何表示某个数字是十进制、二进制、八进制、十六进制
十进制,正常写
二进制,在数字前面加0B或0b
八进制,在数字前面加0
十六进制,在数字前面加0X或0x

3、为什么byte类型的范围是-128~127?
byte是1个字节,1个字节是8位
计算机中是使用“补码”的形式来存储数据的,为了理解/换算“补码”,我们在引入“原码、反码”。
规定:正数的原码、反码、补码三码合一;
	  负数的原码、反码、补码是不同的。
	  因为计算机中把最高位(最左边的二进制位)定为符号位,0表示正数,1表示负数。
正数的原码、反码、补码三码合一
负数的原码、反码、补码是不同的

25:
	原码:0001 1001
	反码:0001 1001
	补码:0001 1001
-25:
	原码:1001 1001
	反码:1110 0110   符号位不变,其余位取反(0变1,1变0)
	补码:1110 0111   在反码上加1
符号位 0 正数  1 负数
负数  反码   补码 - 1



正0: 0000 0000

正数:
	0000 0001   : 1
		|
	0111 1111	: 127
	2^7-1 = 127
负数:补码
	1000 0001	:  补码(1000 0001)-》反码(1000 0000)--》原码(1111 1111) -127
		|
	1111 1111	:	补码(1111 1111)-》反码(1111 1110)--》原码(1000 0001)-1

负0:1000 0000	如果用它表示负0,就浪费了,所以用它来表示其他的数
	-127的二进制的补码:1000 0001
	1的二进制的补码:0000 0001
    1000 0000  -128
    计算机中用符号位来表示正、负
	-127 - 1 = (补码:1000 0001)-(补码:0000 0001) = 补码(1000 0000) = -128
	计算机中用符号位来表示正、负,就是为了底层设计的简化,让符号位也参与计算。

*/
class Test01_JinZhi{
    public static void main(String[] args){
        System.out.println(10);//十进制,正常写
        System.out.println(0B10);//二进制,在数字前面加0B或0b
        System.out.println(0b10);//二进制,在数字前面加0B或0b
        System.out.println(010);//八进制,在数字前面加0
        System.out.println(0X10);//十六进制,在数字前面加0X或0x
        System.out.println(0x0f);//15
    }
}

float和double在底层如何存储?

/*
了解:浮点型的float和double在底层如何存储?
计算机中只有二进制?
那么如果存储3.14?
小数涉及:(1)整数部分(2)小数部分(3)这个.(4)正负号
如何底层存储呢

计算机中只有二进制?
那么如何存储3.14呢?

化繁为简:
1、小数-->二进制:
(1)整数部分:除2倒取余
(2)小数部分:乘2取整数部分
小数 二进制
整数部分 除2倒取余
3.14==》11.00100...
截取
2、把这个二进制用科学记数法表示
	1.1 00100.... * n的1次方
用科学计数法表示后,对于二进制的科学计数法,整数部分永远是1,那这样的话,
整数部分就不用存了,小数点也不存了
移动  移位   整数部分永远是1 小数点也不需要存储了

只要存三个内容:(1)正负号(2)挪完后的几次方,指数(3)二进制的小数部分(称为尾数)
float:4个字节,就被分为三个部分,最高位还是符号位,
接下来的8位用来存指数部分,然后剩下的存尾数,额如果存不下的尾数,就舍去了
1 8 23
double:8个字节,就被分为三个部分,最高位还是符号位,
接下来的11位用来存指数部分,然后剩下的存尾数,额如果存不下的尾数,就舍去了
1 11 52
了解:
(1)浮点类型不精确,因为十进制的小数部分转二进制会需要舍去
(2)float类型的4个字节能表示的数字范围比long类型的8个字节还要大
因为浮点型底层存的是指数

*/
public class Test02_FloatDoubleSave{
}

基本类型转换

/*
基本数据类型之间的转换:
(1)自动类型转换
①把存储范围小的类型的值赋值给存储范围大的类型的变量,自动可以完成升级
byte->short->int->long->float->double
		char->
②boolean不参与
③byte,short,char如果进行算术运算都会自动升级为int


(2)强制类型转换
①把存储范围大的类型的值,赋值给存储范围小的类型变量时,需要强制类型转换
double->float->long->int->short->byte
						->char
大的给小的   溢出 sun损失精度
强制类型转换是有风险的:可能会溢出或损失精度
②boolean不参与
③当需要把某个存储范围小的变量强制提升为存储范围大的类型时,也可以使用强制类型转换
*/
class Test03_TypeChange{
    public static void main(String[] args){
		/*
		从左边看d1是double类型
		从右边看10是int类型
		int类型的值,赋值给了double类型的变量,那么它会自动升级为double
		*/
        double d1 = 10;
        System.out.println("d1 = " + d1);//d1 = 10.0


		/*
		从左边看i1是int类型
		从右边看10.0是double类型
		double类型的值,赋值给int类型的变量,如果直接赋值会报错:错误: 不兼容的类型: 从double转换到int可能会有损失
		*/
        //int i1 = 10.3;
        int i1 = (int)10.3;
        System.out.println("i1 = " + i1);//i1 = 10

        byte b1 = 127;
        byte b2 = 2;
        //byte b3 = b1 + b2;//报错:不兼容的类型: 从int转换到byte可能会有损失,因为byte+byte就自动升级为int
        byte b3 = (byte)(b1 + b2);
        // 0111 1111  0000 0010    1
        // 1000 0001
        // 反码 1000 0000  原码 1111 1111  -127
        System.out.println("b3 = " + b3);//b3 = -127

        short s1 = 1;
        short s2 = 2;
        //short s3 = s1 + s2;//short+short会自动升级为int
        short s3 = (short)(s1 + s2);
        System.out.println("s3 = " + s3);//s3 = 3

        char c1 = '0';//'0'的编码值是48
        char c2 = '1';//'1'的编码值是49
        //char c3 = c1 + c2;//char+char会自动升级为int
        char c3 = (char)(c1 + c2);
        System.out.println("c3 = " + c3);//'a' 97
        //c3 = a

        boolean flag = true;
        //int num = (int)flag;//不兼容的类型: boolean无法转换为int

        int x = 1;
        int y = 2;
        System.out.println("x / y = " + x/y);//整数/整数,结果还是整数,只保留整数部分
        System.out.println("x / y = " + (double)x/y);//把x的int类型先强制升级为double类型

    }
}
/*
数据类型转换的特例:字符串类型
	所有类型与字符串“+”拼接,结果都是字符串
*/
class Test04_TypeChange{
    public static void main(String[] args){
        char c1 = '0';
        char c2 = '1';

		/*
		c1 + c2,按照求和运算,char + char结果是int
		""代表空字符串,
		当int的97与""进行 “+”拼接,结果还是97的字符串
		*/
        System.out.println(c1 + c2 + "");//97
        // '0' + '1' int + ""  48 + 49  97

		/*
		"" + c1,按照“拼接”运算,字符串 + char,结果是字符串,结果是"0"
		"0" + c2,按照“拼接”运算,字符串 + char,结果是字符串,结果是"01"
		*/
        System.out.println("" + c1 + c2 );//01

		/*
		c1 + "",按照“拼接”运算,char + 字符串 ,结果是字符串,结果是"0"
		"0" + c2,按照“拼接”运算,字符串 + char,结果是字符串,结果是"01"
		*/
        System.out.println(c1 + "" + c2 );//01
    }
}

posted @ 2020-05-08 01:30  渐若窥宏大  阅读(308)  评论(0编辑  收藏  举报