【JavaSE】数据类型和运算符

文章目录

  • 一. 数据类型
    • 1. 整数类型
      • 1.1 整型(int)
      • 1.2 长整型(long)
      • 1.3 字节类型(byte)
      • 1.4 短整型(short)
    • 2. 浮点数类型
      • 2.1 双精度浮点型(double)
      • 2.2 单精度浮点型(float)
    • 4. 字符类型(char)
    • 4. 字符串类型(String)
    • 5. 布尔类型(boolean)
    • 6. 几点补充
      • 6.1 变量命名规则
      • 6.2 区分常量和变量
      • 6.3 理解类型转换
      • 6.4. 理解类型提升
      • 6.5 int和String之间的相互转换
  • 二. 运算符
    • 1. 算术运算符
    • 2. 关系运算符
    • 3. 逻辑运算符
    • 4. 位运算符
    • 5. 移位运算符
    • 6. 条件运算符
  • 三. 注释
    • 1. 基本规则
    • 2. 注释规范

一. 数据类型

Java中一共有8中基本数据类型,此外还有很多引用数据,它们如下图所示:
【JavaSE】数据类型和运算符_第1张图片

1. 整数类型

注意:Java当中的整数没有所谓的无符号(unsigned)类型,统一都是有符号的。

1.1 整型(int)

下面定义一个整型变量:

int num = 10;

注意事项:

  1. 变量指的是程序运行时其值可以改变的量
  2. 类型则是对变量的种类进行了划分,不同的类型的变量具有不同的特性
  3. 变量名是变量的标识,后续都是通过这个名字来使用变量
  4. int 表示变量的类型是一个整型
  5. Java中 = 表示赋值(和数学不一样,数学中表示等价),意思是给变量设置一个初始值或重新给值。
  6. 初始化操作是可选的,但是建议创建变量的时候都显式初始化
  7. 不要忘记最后的分号,否则会编译失败

int类型的大小和表示范围

在Java中,一个int类型的变量占4个字节(即32个bit位)和操作系统没有直接关系,这充分说明了Java的可移植性强。4个字节表示的数据范围是[-2^31, +2^31-1]

【JavaSE】数据类型和运算符_第2张图片

使用以下代码查看Java中的int数据范围:

// 输出:2147483647
System.out.println(Integer.MAX_VALUE);
// 输出:2147483648
System.out.println(Integer.MIN_VALUE);

PS:Integer是int的包装类,相当于int的puls版本。

如果运算的结果超出了int的最大范围,就会出现溢出的情况:
【JavaSE】数据类型和运算符_第3张图片

1.2 长整型(long)

21亿这样的数字对于当前的大数据时代来说,是很容易超出的,针对这种情况,我们就需要使用更大范围的数据类型来表示。Java中提供了long类型。

下面定义三个长整型变量:

// long类型变量的值有以下三种写法
long num1 = 10;
long num2 = 10L;
long num3 = 10l;

注意事项:

  1. 初始化设定的值为10L表示这是一个长整型的字面常量,10l也可以。
  2. 使用10初始化也可以,10字面常量的类型是int,赋值时会发生整型提升。10L的类型是long,使用10L或者10l更好一些。
  3. Java中没有long long类型。

long类型的大小和表示范围

Java中long类型占8个字节,表示的数据范围[-2^63, +2^63-1],使用以下代码查看Java中长整型的数据范围:

// 输出:9223372036854775807
System.out.println(Long.MAX_VALUE);
// 输出:-9223372036854775808
System.out.println(Long.MIN_VALUE);

这个数据范围远超过int的表示范围,足够绝大部分的工程场景使用。

1.3 字节类型(byte)

只占一个字节的byte类型只能表示整数;注意和C/C++中的char区分开,char表示出来的是字符。

byte num = 1;

注意事项:

  1. 字节类型和字符类型互不相干。
  2. 字节类型表示的也是整数。只占一个字节, 表示范围较小[-128, +127]
  3. 在Java当中,整数类型都是有取值范围的,存储数据的时候,不要超过那个范围,编译器会针对类型对变量的值进行检查是否在合法范围内。
    【JavaSE】数据类型和运算符_第4张图片

1.4 短整型(short)

和C/C++一样,Java中也有short类型。

short num = 10;

注意事项:

  1. short类型占用2个字节,表示的数据范围是[-32768,+32767]
  2. 这个表示范围比较小,一般不推荐使用。

2. 浮点数类型

浮点数类型有两种:float、double,它们能表示的精度不一样,后者要大一些。

2.1 双精度浮点型(double)

double a = 1.0;
double b = 2.0;
System.out.println(a / b);// 0.5

Java中的double是8个字节,但实际上浮点数的内存布局和整数差别很大,我们看下面这段代码:

double num = 1.1;
// 输出 1.2100000000000002
System.out.println(num * num);

Java中double类型的内存布局遵守IEEE 754标准(和C语言一样),尝试使用有限的内存空间表示可能的无限小数,这势必会存在一定的精度误差,所以不能单纯地用2^n形式表示来表示浮点数的数据范围。

2.2 单精度浮点型(float)

float类型在Java中占4个字节,同样遵守IEEE 754标准。由于表示的数据精度范围较小,一般在工程上用到浮点数都优先考虑double,不推荐使用 float。

float num = 1.1f;// 写作1.1F也可以,但不能不写

注意:float类型的变量在初始化给值时一定要加上f或F的标识。不然会报错:java: 不兼容的类型: 从double转换到float可能会有损失,因为在Java中浮点数字面常量值的类型默认是double(8字节)的,如果直接把它赋值给float(4字节)变量会有数据损失。

4. 字符类型(char)

char ch = 'A';
// 打印字符A的三种方法
System.out.println(ch);// 通过char类型变量来打印
System.out.println('A');// 通过字符的字面常量来打印
System.out.println((char)65);// 通过'A'的Unicode码来表示

注意事项:

  1. Java中使用单引号 + 单个字母的形式表示字符的字面常量。
  2. 计算机中存储的字符本质上还是一个整数,在C语言中使用ASCII来表示字符,而Java中使用Unicode表示字符,因此在Java中一个字符占用两个字节,两个字节的话可以表示的字符种类更多,包括中文。
    【JavaSE】数据类型和运算符_第5张图片

4. 字符串类型(String)

和上面的类型不同,String不是基本类型,而是引用类型。Java中使用双引号 + 若干字符的方式表示字符串常量值:

【JavaSE】数据类型和运算符_第6张图片
注意事项:

  1. 字符串中的一些特定的不太方便直接表示的字符需要进行转义:
    【JavaSE】数据类型和运算符_第7张图片
  2. 字符串的 + 操作,表示字符串拼接:
    【JavaSE】数据类型和运算符_第8张图片
  3. 当一个 + 表达式两边中存在至少一个字符串操作数的时候,执行的都是字符串拼接行为:
    【JavaSE】数据类型和运算符_第9张图片

5. 布尔类型(boolean)

相当于C++中的bool类型,在Java中叫做boolean,不过二者还是有区别的。

boolean flag = true;

注意事项:

  1. boolean类型的变量只有两种取值:true和false,不能再有其他取值。
  2. Java中的boolean类型和int不能相互转换,不存在0表示false,非0表示true这样的说法。
    【JavaSE】数据类型和运算符_第10张图片
  3. 在JVM的规范当中,并没有规定布尔类型的大小。有些书会说1bit,有些书又说是1byte,这个没有明确规定。

6. 几点补充

6.1 变量命名规则

硬性规则(必须遵守)

  1. 变量名必须由数字、字母(大小写都可)、下划线构成,不能包含其他特殊符号。
  2. 数字不能开头:
    【JavaSE】数据类型和运算符_第11张图片
  3. 变量名不能和Java的“关键字”重复。
  4. Java中的变量名是大小写敏感的,例如num和Num是两个不同的变量。

软性规则(建议遵守)

  1. 变量名的词性推荐使用名词。
  2. 变量命名要具有描述性,能够见名知义。
  3. 当我们使用一个单词描述不清楚的时候,可以使用多个单词来命名。这时变量命名推荐小驼峰命名法,即除了第一个单词之外,后面单词的首字母都大写,如下图所示:
    【JavaSE】数据类型和运算符_第12张图片

6.2 区分常量和变量

【JavaSE】数据类型和运算符_第13张图片

6.3 理解类型转换

Java作为一个强类型编程语言,当不同类型之间的变量相互赋值的时候, 会进行较严格的校验,先看以下几个代码场景:

场景一:int 和 long/double 相互赋值

int a = 10;
long b = 20;
a = b; // 编译出错,提示可能会损失精度
b = a; // 编译通过

int a = 10;
double b = 1.0;
a = b; // 编译出错, 提示可能会损失精度.
b = a; // 编译通过.

分析:

  1. long表示的范围更大,可以将int赋值给long,但是不能将long赋值给int。
  2. double表示的范围更大,可以将int赋值给double,但是不能将double赋值给 int。

结论:不同数字类型的变量之间赋值:精度可以扩大但不能缩小,即使类型改变了也要尽可能的地保护数据安全。

场景二:int 和 boolean 相互赋值

int a = 10;
boolean b = true;
b = a; // 编译出错, 提示不兼容的类型
a = b; // 编译出错, 提示不兼容的类型

结论:int和boolean是毫不相干的两种类型,二者不能相互赋值。

场景三:整型字面值常量给 byte 赋值

// PS: 1、byte表示的数据范围是[-128, +127]
//     2、256已经超过了byte的范围, 而100还在范围之内
byte a = 100; // 编译通过
byte b = 256; // 编译报错, 提示:从int转换到byte可能会有损失

结论:使用字面值常量赋值的时候,Java会自动进行一些检查校验,判定赋值是否合理:

  • 整数的话,会检查字面常量值是否在变量类型所能表示范围之内。
  • 浮点数的话,会检查是否会有精度丢失,注意浮点数字面常量值类型默认是double,如果要赋值给float的话需要在数字最后加上F或f表示这个浮点数字面常量是float类型的。

创建四:使用强制类型转换

int a = 0;
double b = 10.5;
a = (int)b;// 编译通过

int a = 10;
boolean b = false;
b = (boolean)a; // 编译出错, 提示不兼容的类型

结论:

  1. 强制类型转换可能会导致精度丢失,如上面的例子中,赋值之后,10.5 就变成10了,小数点后面的部分被丢弃。
  2. 强制类型转换不是一定能成功,互不相干的类型之间就无法强转。

类型转换小结

  • 不同数字类型的变量之间赋值,表示范围更小的类型能自动隐式类型转换成范围较大的类型。
  • 不同数字类型的变量之间赋值,如果需要把范围大的类型赋值给范围小的,需要强制类型转换,但是可能会发生精度丢失。
  • 将一个字面值常量进行赋值的时候,Java会自动针对这个数字和变量的类型所能表示的范围进行检查:
    • 整数的话,会检查字面常量值是否在变量类型所能表示范围之内。
    • 浮点数的话,会检查是否会有精度丢失,注意浮点数字面常量值类型默认是double,如果要赋值给float的话需要在数字最后加上F或f表示这个浮点数字面常量是float类型的。

6.4. 理解类型提升

不同数字类型的变量在运算时会发生数值提升,具体看下面两个场景:

场景一:int 和 long 混合运算

int a = 10;
long b = 20;
int c = a + b; // 编译出错,提示将long转成int会丢失精度
long d = a + b;// 编译通过

分析:

  • 当int和long混合运算的时候,int会提升成long,得到的结果仍然是long类型,需要使用long类型的变量来接收结果。
  • 如果非要用int来接收结果,就需要进行强制类型转换。

场景二:byte 和 byte 的运算
【JavaSE】数据类型和运算符_第14张图片
分析:

  • 由于计算机的CPU通常是按照4个字节为单位从内存中读写数据,为了硬件上实现方便,诸如byte和short这种低于4个字节的数字类型,会先提升成int,再参与计算。
  • byte和byte都是相同类型,但是出现编译报错,原因是:虽然a和b都是 byte,但是计算a+b时会先将a、b都提升int,再进行计算,最终得到的结果也是int,这是赋给c,就会出现上述错误。
  • 而右边10和20都是普通的整型字面常量,最终结果30也是一个普通字面常量,所以不会报错。

类型提升小结

  • 不同数字类型的变量混合运算,范围小的会提升成范围大的,最后得到的结果是一个类型范围最大的临时变量。
  • 对于short、byte这种小于4个字节数字类型,会先提升成4个字节的int再做运算。

6.5 int和String之间的相互转换

int转成String:利用String包装类的valueOf()方法,即可返回一个String类型的由整数转化而来的字符串,注意 valueOf 中的O是大写的。

int num = 10;
String s = String.valueOf(num);

String转成int:利用Integer包装类的parseInt()方法,把需要转化的字符串作为参数传入即可,注意 parseInt 中的I是大写的。

String s = "10";
int num = Integer.parseInt(s);

小结:对标C++中的转换

【JavaSE】数据类型和运算符_第15张图片

二. 运算符

PS:运算符之间是有优先级的,我们不需要去记忆谁的优先级高或低,只需根据自己的逻辑加上括号即可。

1. 算术运算符

算术运算符包括如下三个大类:
【JavaSE】数据类型和运算符_第16张图片
注意事项:

  • %表示取余,不仅仅可以对int求模,也能对double来求模
    【JavaSE】数据类型和运算符_第17张图片
  • 取模就是取余数,最终结果的正负号取决于余数
    【JavaSE】数据类型和运算符_第18张图片
  • 0不能作为除数和取模数
    【JavaSE】数据类型和运算符_第19张图片
  • 自增/自减运算符,都有各自的前置和后置形式。自增使用时注意以下两点:
    • 如果不取自增运算的表达式的返回值,则前置自增和后置自增没有区别
    • 如果取表达式的返回值,则前置自增的返回值是自增之后的值,后置自增的返回值是自增之前的值。

2. 关系运算符

关系运算符主要有六个:> < >= <= == !=,注意关系运算符的表达式返回值都是boolean类型。

int a = 10;
int b = 20;
System.out.println(a == b);// false
System.out.println(a != b);// true
System.out.println(a < b); // true
System.out.println(a > b); // false
System.out.println(a <= b);// true
System.out.println(a >= b);// false

3. 逻辑运算符

逻辑运算符主要有三个:&& || !,注意逻辑运算符的操作数(操作数往往是关系运算符的结果)和返回值都是boolean。

逻辑与 &&:全true才true,都则为false,这是个双目运算符

// 对于&&,如果左侧表达式值为false,
// 则表达式的整体的值一定是false,无需计算右侧表达式
System.out.println((10 > 20) && (10/0 == 0));// 打印 false

逻辑或 ||:全flase才false,否则为true,这是个双目运算符

// 对于||,如果左侧表达式值为true
// 则表达式的整体的值一定是true, 无需计算右侧表达式
System.out.println((10 < 20) || (10 / 0 == 0));// 打印 true

逻辑非 !:操作数为true,结果为false;操作数为false,结果为true(这是个单目运算符,只有一个操作数)

int a = 10;
int b = 20;
System.out.println(!(a < b));// fasle

4. 位运算符

位运算符主要有四个:& | ~ ^。Java中对数据操作的最小单位不是字节, 而是二进制位,而位操作表示的就是按二进制位运算。

计算机内部都是使用二进制来存储和表示数据的(即01构成的序列), 位运算就是在按照二进制位的每一位依次进行计算。

按位与 &:这是个双目运算符。两个二进制位中有0则结果为0,都是1结果才为1。
【JavaSE】数据类型和运算符_第20张图片
按位或 |:这是个双目运算符。两个二进制位中有1则为1,都是0结果才为0。
【JavaSE】数据类型和运算符_第21张图片
按位取反 ~:这是个单目运算符,运算规则如下:

  • 如果该二进制位为0,则转为1
  • 如果该二进制位为1,则转为0

5. 移位运算符

移位运算符有三个:<< >> >>>,它们都是按照二进制位来运算的。

左移 <<:最左侧位不要了,最右侧补0
【JavaSE】数据类型和运算符_第22张图片

右移 >>:最右侧位不要了,最左侧补符号位(正数补0,负数补1)
【JavaSE】数据类型和运算符_第23张图片

无符号右移 >>>:最右侧位不要了,最左侧不论正负数,统一都补0

移位运算符小结

  1. 左移 1 位,相当于原数字 * 2。左移 N 位,相当于原数字 * 2的N次方
  2. 右移 1 位,相当于原数字 / 2。右移 N 位,相当于原数字 / 2的N次方
  3. 在计算机中计算移位的效率高于计算乘除,当某个代码正好乘除2的N次方的时候,我们可以用移位运算代替,这样效率会高点。
  4. 移动负数位或者移位位数过大都没有意义

6. 条件运算符

条件运算符只有一个,也是Java中唯一的一个三目运算符。其格式如下:

表达式1 ? 表达式2 : 表达式3

  • 当表达式1的值为true时,整个表达式的结果为表达式2的值(表达式3不会被执行)
  • 当表达式1的值为false时,整个表达式的值为表达式3的值(表达式2不会被执行)

三. 注释

注释是为了让代码更容易被读懂而附加的描述信息。不参与编译运行,但是却非常重要。

时刻牢记!代码写出来是为了给人看的,更是为了给三个月后的你自己看的。

1. 基本规则

Java中的注释主要分为以下三种:

  • 单行注释:// 注释内容(用的最多)
  • 多行注释:/* 注释内容 */(不推荐)
  • 文档注释: /** 文档注释 */(常见于方法和类之上描述方法和类的作用),可用来自动生成文档。

2. 注释规范

  1. 内容准确:注释内容要和代码一致、匹配,并在代码修改时及时更新
  2. 篇幅合理:注释既不应该太精简,也不应该长篇大论
  3. 使用中文:一般中国公司都要求使用中文写注释,外企另当别论
  4. 积极向上:注释中不要包含负能量(例如:领导SB等)

你可能感兴趣的:(JavaSE,java,开发语言)