Java基本语法_02_数据类型


本质上说,程序就是对数据的处理。不同的编程语言为了满足自己的语言优势和特色,结合设计理念制定了不同的数据类型以及存储方式。本文主要介绍数据类型、字面值、变量和常量等相关内容。

1. 数据类型

1.1 数据类型的作用

程序中有很多数据,每一个数据都是有类型的,不同类型的数据占用内存空间大小不同,数据类型的作用是指导JVM在运行程序的时候给该数据分配多大的内存空间。

Java中的数据类型包括两种:

  1. 基本数据类型:如int,char等;
  2. 引用数据类型,如数组,字符串,类对象等。(后面面向对象部分介绍)

1.2 基本数据类型

和C/C++类似,Java中的基本数据类型包括四大类八小类,如下所示:

  1. 整数型:byte, short, int, long
  2. 浮点型:float, double
  3. 布尔型:boolean
  4. 字符型:char

具体每个类型所占内存空间大小相关信息如下表所示:

数据类型 占用空间大小(字节) 取值范围(无符号) 取值范围(有符号) 默认值
byte 1 0 ~ 255 -128 ~ 127 0
short 2 0 ~ 65535 -32768 ~ 32767 0
int 4 0
long 8 0L
float 4 0.0
double 8 0.0
boolean 1 true/false false
char 2 0 ~ 65535 \u0000
引用数据类型 null

1.2.1 整数型

Java语言中的整数型有四种,取值范围从小到大分别是byte, short, int, long。除了数据类型,还有不同的表示方式,Java语言中整数型一共有三种表示方式:

  • 十进制(默认):普通数字。

    如:10,15,20等等。

  • 八进制:以 0 开头。

    如:010,011,012,分别表示十进制的8,9,10。

  • 十六进制:以 0x 开头。

    如:0x10,0x11,0x12,分别表示十进制的16,17,18。

既然存在四种整数类型,那么对于一个整数型数据,比如 732,那么它是哪个类型呢?在Java语言中,默认被当做int类型来处理,即使这个数值超过了int的取值范围,它仍然是被当做int类型,只不过会报错,这个时候需要在数值后面加上字母L,如1234567L,即代表long类型,见后面的字面值部分。对于byte和short,见后续的变量以及类型转换。

1.2.2 浮点型

Java语言中的浮点型有两种,取值范围从小到大分别是float, double。float是单精度,double是双精度。但是相对来说,double的精度也不是很高,对于财务类数据,double仍然不够,为此,Java提供了java.math.BigDecimal类型。

在Java语言当中,所有的浮点型数据默认被当做是double类型处理,如果想让Java当做float类型来处理,需要在字面值后面加上字母f或F。

注意,double和float在计算机内部二进制存储的时候存储的都是近似值。在现实世界当中有一些数字是无限循环的,例如:3.3333333333…。计算机的资源是有限的,用有限的资源存储无限的数据只能存储近似值。

1.2.3 布尔型

Java语言中的布尔型只有一种boolean,取值为true和false两个。布尔类型数据在实际开发中非常重要,经常用在逻辑运算和条件控制语句当中。

1.2.4 字符型

Java语言中的字符型只有一种char,占用两个字节,可以表示65535个数字,将字符编码并转换成对应的数字,即char可表示65535个字符。

1.3 字符编码

有了数据类型,那么计算机是如何存储这些数据呢?

众所周知,计算机是根据电脉冲的有无来执行指令的,而电脉冲的有无则表示0和1,也就是只能表示二进制。那么对于上述的整数型(十进制),则需要进制转换。对于浮点型,本质上也是十进制,只不过需要分别表示整数位和小数位。对于布尔型,因为只有两个取值,直接一一映射即可。对于字符型,一方面字符的取值较多,另一方面,字符的取值和二进制之间没有关系,所以需要对字符进行编码(使其和二进制有关系),然后进行一一映射。

编码不是什么了不起的东西,就是同一种事物的另一种表示形式而已。比如,人,不可能实际存储在计算机中,就用他的身份证号表示。对于字符,计算机无法存储,只能先存储它的编码,然后在显示器显示的时候,进行转换。

最早的编码是ASCII码,只能编码英文。后来随着计算机的发展,出现了一种编码方式,它是国际化标准组织ISO制定的,这种编码方式支持西欧语言,向上兼容ASCII码,仍然不支持中文。这种编码方式是ISO-8859-1,又被称为Latin-1。

随机计算机向亚洲发展,计算机开始支持中文、日文、韩文等国家文字,其中支持简体中文的编码方式有:GB2312 , GBK , GB18030。支持数量由少到多,其中GB2312支持的中文数量最少。支持繁体中文的有:Big5。

后来又出现了一种编码方式统一了全球所有的文字,容量较大,这种编码方式叫做:Unicode编码。Unicode编码方式有多种具体的实现:比如UTF-8,UTF-16,UTF-32等等。Java语言源代码采用的是Unicode编码方式,所以“标识符”可以用中文

JDK自带的native2ascii命令工具可以将中文转换成Unicode编码。(似乎JDK9及以后的就没有了该命令)。

1.4 类型转换

既然存在不同的数据类型,那么Java也提供了数据类型之间的转换(具体的例子见后面的字面值以及变量部分)。类型转换分为两种:

  • 自动类型转换

    从小容量到大容量的数据转换,Java会自动执行。其实相当于直接在数字的前面填充0即可,使其满足特定字节的长度即可。

  • 强制类型转换

    从大容量到小容量的数据转换,需要手动执行,但是这仅仅是编译通过了,在实际运行过程中,可能会损失精度。其实相当于直接从前面截断,比如long类型转换到int类型,直接将前面四个字节截断,取后四个字节。

    语法:int a = (long)1234567L;

1.4.1 基本数据类型之间的互相转换

  1. 八种基本数据类型当中除布尔类型之外剩下的7种类型之间都可以互相转换。

  2. 小容量向大容量转换,称为自动类型转换,容量从小到大排序:(注意是容量,不是占的字节数)

    byte < short < int < long < float < double

    ​ char <

    注意:任何浮点类型不管占用多少个字节,都比整数型容量大。

    ​ char和short可表示的种类数量相同,但是char可以取更大的正整数(因为char没有符号,不分正负)。

  3. 大容量转换成小容量,叫做强制类型转换,需要加强制类型转换符,程序才能编译通过,但是在运行阶段可能会损失精度,所以谨慎使用。

  4. 当整数字面值没有超出byte,short,char的取值范围,可以直接赋值给byte,short,char类型的变量。

  5. byte,short,char混合运算的时候,各自先转换成int类型再做运算

  6. 多种数据类型混合运算,先转换成容量最大的那种类型再做运算

注意:编译的时候仅仅检查语法,而不会运算检查结果。比如,int a = 10; short b = a;,这样就会出错,因为a是int类型的,赋值给b,需要强转,而没有强转,所以报错。(不会因为a是10,在short类型的范围内,就不报错,不会检查结果)。

2. 字面值

字面值就是程序中实际存在的值,字面值就是数据,看到它就知道它具体的值。比如3.14'a'100等等。根据数据类型的不同,字面值也分为不同的种类:

  • 整数型字面值
  • 浮点型字面值
  • 字符型字面值
  • 字符串型字面值
  • 布尔型字面值

注意,Java语言当中所有的字符串型字面值必须使用双引号括起来;Java语言当中所有的字符型字面值必须使用单引号括起来。在程序中,如果有字面值,那么就会开辟一块内存空间,(不管字面值的值是否一样)。

3. 变量

程序本质上是对数据的处理,数据需要开辟内存空间存储,为了高效地利用内存空间,在一些数据不用之后,可以重新在这块内存空间上存储其他同种类型数据,为了找到这块内存空间,给这块内存空间起了一个名字,名字+内存空间存储的值+数据类型=变量。

变量本质上来说是内存中的一块空间,这块空间有“数据类型”、“名字”、“字面值”。即变量包含三部分:数据类型,名称,字面值(数据)

变量的相关语法如下:

1
2
3
4
5
6
7
// 声明变量,即说明这个变量的数据类型和名称,还没有赋值
int a;
// 给变量赋值,将字面值 100 赋值给变量a。
a = 100;

// 声明变量并赋值
int b = 200;

变量是内存中存储数据的基本单元。有了变量之后,内存空间得到了重复使用。比如int a = 10;int b = 10;那么此时两个10字面值都是指的是一块内存空间。注意和字面值的区别,如果字面值单独存在,那么即使值相同,也会单独开辟空间,而赋值给变量后,就会仅开辟一块空间。

注意:在方法体中的Java代码,是遵守自上而下的顺序依次执行的,逐行执行。所以必须先声明变量才能使用该变量。

4. 常量

常量就是定义之后,其值不会再变化的变量。比如在程序中定义了PI,值为3.1415926。这个值是公认的,为了避免后续误操作被修改,可以在变量前添加修饰符final。

5. 例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class Example{

public static void main(String[] args){

// 整数型数字,默认是int类型,这里的byte和short,大容量向小容量数据转换。
// 这里有一个特殊情况,当一个字面值没有超过byte, short, char的取值范围,这个字面值是可以直接赋值给byte,short,char的变量,而不需要强制类型转换。
byte a = 10;
short b = 11;

// byte aa = 128; // 报错,因为 128 超过了byte的范围,必须强转。
byte aa = (byte)128; // 强转

int c = 12;

long d = 13L;

// 小容量向大容量 数据类型转换,自动转换
long dd = 13;

char e = 'e';

boolean f = true;

float g = 3.14f;
double h = 2.71828;

// 常量,定义之后无法再修改它的值。
final double PI = 3.14;

System.out.println("Hello World!");
}
}

6. 备注

参考B站《动力节点》。


文章作者: 浮云
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 浮云 !
  目录