Java数据类型与运算符

1. 变量和类型

变量指的是程序运行时可变的量,相当于开辟一块空间来保存一些数据。

类型则是对变量的种类进行了划分,不同类型的变量具有不同的特性。

1.1 整型变量(重点)

基本语法格式:

java 复制代码
int 变量名 = 初始值;

代码示例:

java 复制代码
int num = 10; //定义一个整型变量
System.out.println(num);

注意事项:

  • int 表示变量的类型是一个整型
  • Java中'='表示赋值,意思是给变量设置一个初始值。
  • 初始化操作是可选的,但是建议创建变量的时候都先初始化。
  • 每个语句写完后不要忘记封号,否则会编译失败。
  • '//'表示注释,注释作为代码的解释说明部分,不参与编译运行。
    在Java中,一个int变量占4个字节,和操作系统没有直接关系。
    什么是字节?
  • 字节是计算机表示空间大小的基本单位。
  • 计算机使用二进制表示数据,我们认为8个二进制位(bit)为一个字节(Byte)。
  • 我们平时的计算机为8GB内存,意思是8G个字节。
  • 其中1KB = 1024Byte, 1MB = 1024KB, 1GB = 1024MB.
  • 所以8GB相当于80多亿个字节。
    4个字节表示的数据范围是-2^31^ -> 2^31-1^ ,也就是-21亿到+21亿。
    使用以下代码可以查看Java中的整型数据范围:
java 复制代码
System.out.println(Integer.MAX_VALUE);//int 的最大值
System.out.println(Integer.MIN_VALUE);//int 的最小值

如果运算的结果超出了int的最大范围,就会出现溢出的情况

java 复制代码
int maxValue = Integer.MAX_VALUE;
System.out.println(maxValue+1);

int minValue = Integer.MIN_VALUE;
System.out.println(minValue-1);

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

1.2 长整型变量

基本语法格式:

java 复制代码
long 变量名 = 初始值;

代码示例:

java 复制代码
long num = 10L;//定义一个长整型变量,初始值写作10L(建议后面的L大写,防止和数字1混淆)
System.out.println(num);

注意事项:

  1. 基本语法格式和创建int 变量基本一致,只要把类型修改成long。
  2. 初始化设定的值为10L,表示一个长整型的数字。
    Java中long类型占8个字节,表示的数据范围-2^63^ ->2^63-1^
    使用以下代码查看Java中的长整型数据范围:
java 复制代码
System.out.println(Long.MAX_VALUE);
System.out.println(Long.MIN_VALUE);

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

1.3 双精度浮点型变量(重点)

基本语法格式:

java 复制代码
double 变量名 = 初始值;

代码示例:

java 复制代码
double n = 1.0;
System.out.println(n);

神奇的代码1:

java 复制代码
int a = 1;
int b = 2;
System.out.println(a / b);
//执行结果:0

在Java中,int 除以 int 的值仍然是int(会直接舍弃小数部分)。

如果想得到0.5,需要使用double类型计算。

java 复制代码
double a = 1;
double b = 2;
System.out.println(a / b);
//执行结果:0.5

神奇的代码2:

java 复制代码
double a = 1.1;
System.out.println(num * num);
//执行结果:1.2100000000000002

Java中的double虽然也是8个字节,但是浮点数的内存布局和整数差别很大,不能单纯的用2^n^ 的形式表示数据范围。

Java的double类型的内存布局遵守IEEE 754标准(和C语言一样),尝试使用有限的内存空间表示可能无限的小数,势必会存在一定的精度误差。

1.4 单精度浮点型变量

基本格式:

java 复制代码
float 变量名 = 初始值;

代码示例:

java 复制代码
float num = 1.0f; //写作 1.0F 也可以
System.out.println(num);

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

1.5字符类型变量

基本格式:

java 复制代码
char 变量名 = 初始值;

代码示例:

java 复制代码
char ch = 'A';

注意事项:

  1. Java中使用单引号+单个字符表示字面值。
  2. 计算机中的字符本质上是一个整数,在C语言中使用ASCII表示字符,而Java中使用Unicode表示字符,因此一个字符占用两个字节,表示的字符种类更多,包括中文。
    使用一个字符表示一个汉字:
java 复制代码
char ch = '狸';
System.out.println(ch);

执行Javac的时候可能出现以下错误:

java 复制代码
Test.java:3:错误:未结束的字符文字
       char ch = '鍛?';

此时我们在执行javac时加上-encoding UTF-8选项即可

java 复制代码
java -encoding UTF-8 Test.java

1.6 字节类型变量

基本语法格式:

java 复制代码
byte 变量名 = 初始值;

代码示例:

java 复制代码
byte value = 0;
System.out.println(value);

注意事项:

  1. 字节类型表示的也是整数,只占一个字节,表示范围较小(-128 -> +127)。
  2. 字节类型和字符类型互不相干。

1.7 短整型变量

基本语法格式:

java 复制代码
short 变量名 = 初始值;

代码示例:

java 复制代码
short value = 0;
System.out.println(value);

注意事项:

  1. short占用2个字节,表示的数据范围是-32768 -> +32767。
  2. 这个表示范围较小,一本不推荐使用。

1.8 布尔类型变量

基本语法格式:

java 复制代码
boolean 变量名 = 初始值;

代码示例:

java 复制代码
boolean value = true;
System.out.println(value);

注意事项:

  1. boolean类型的变量只有两种取值,true表示真,false表示假。
  2. Java的boolean类型的变量和int 不能互相转换,不存在1表示true,0表示false这样的用法。
  3. boolean类型有些JVM的实现是占1个字节,有些是占1个比特位,这个没有明确规定。
java 复制代码
boolean value = true;
System.out.println(value + 1);
/*编译会出现如下错误
java: 二元运算符 '+' 的操作数类型错误
  //第一个类型:  boolean
  第二个类型: int/*

1.9 字符串类型变量

把一些字符放到一起就构成了字符串。

基本语法格式:

java 复制代码
String 变量名 = "初始值";

代码示例:

java 复制代码
String name = "ali";
System.out.println(name);

注意事项:

  1. Java使用双引号+若干字符的方式表示字符串字面值。
  2. 和上面的类型不同,String不是基本类型,而是引用类型。
  3. 字符串中的一些特定的不太方便直接表示的字符需要进行转义。
    转义字符示例:
java 复制代码
//创建一个字符串 My name is "阿狸"
String name = "my name is \"阿狸\"";

转义字符有很多,其中几个比较常见的如下:

字符串'+'操作,表示字符串拼接:

java 复制代码
System.out.println(num);
String a = "hello";
String b = "world";
String c = a + b;
System.out.println(c);
//执行结果:helloworld(这里没有空格,可以自己加)

还可以用字符串和整数进行拼接:

java 复制代码
float num = 1.0f;
String str = "result =";
int a = 10;
int b = 20;
String result = str + a + b;
System.out.println(result);
//执行结果:result = 1020

以上代码说明,当一个'+'表达式中存在字符串的时候,都是执行字符串的拼接行为。

因此我们可以很方便的使用System.out.println同时打印多个字符串或数字。

1.10 变量的作用域

也就是该变量能生效的范围,一般是变量定义所在的代码块(大括号)。

java 复制代码
public static void main(String[] args) {
        int x = 10;
        System.out.println(x); //编译通过
    }
    System.out.println(x); //编译失败,找不到x

1.11 变量的命名规则

硬性指标:

1.一个变量名只能包含数字、字母、下划线。

2.数字不能开头。

3.变量名是大小写敏感的,即num和Num是两个不同的变量。

注意:虽然语法上也允许使用中文/美元符($)命名变量,但是强烈建议不推荐这样做。

软性指标:

1.变量命名要具有描述性,见名知意。

2.变量名不宜使用拼音(但是不绝对)。

3.变量名的词性推荐使用名词。

4.变量命名推荐小驼峰命名法,当一个变量名由多个单词构成的时候,除了第一个单词之外,其他单词首字母都大写。

小驼峰命名示例:

java 复制代码
int maxValue = 100;
String studentName = "阿狸";

1.12 常量

上面讨论的都是各种规则的变量,每种类型的变量也对应着一种相同类型的常量。

常量在运行时类型不能发生改变。

常量主要有以下两种体现形式:

  1. 字面值常量
10 int 字面值常量(十进制)
010 int 字面值常量(八进制)由数字0开头,010即十进制的8
0x10 int 字面值常量(十六进制)由数字0x开头,0x10即十进制的16
10L long字面值常量,也可以写作10l(小写的L)
1.0 double 字面值常量,也可以写作1.0d,或者1.0D
1.5e2 double 字面值常量,科学计数法表示,相当于1.5 * 10^2^
1.0f float 字面值常量,也可以写作1.0F
true boolean 字面值常量,同样的还有false
' a ' char 字面值常量,单引号中只能有一个字符
" abc " String 字面值常量,双引号中可以有多个字符
  1. final 关键字修饰的常量
java 复制代码
final int a = 10;
a = 20;//编译出错,无法为最终变量a分配值

常量不能在程序运行过程中发生修改。

1.12 理解类型转换

Java作为一个强类型编程语言,当不同类型之间的变量相互赋值的时候,会有严格的校验。

先看以下几个代码场景:

int 和 long / double 相互赋值

java 复制代码
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 相互赋值

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

结论:

int 和 boolean 是毫不相干的两种类型,不能相互赋值。

int 字面值常量给 byte 赋值

java 复制代码
byte a = 100;//编译通过
byte b = 256;//编译报错,从int 转换到byte 可能会有损失

注意:byte 表示的数据范围是-128 -> +127,256已经超过范围,而100还在范围之内。
结论:

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

使用强制类型转换

java 复制代码
int a = 0;
double b = 10.5;
a = (int)b;

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

结论:

使用(类型)的方式可以将double 类型强转成 int 。但是

1.强制类型转换可能会导致精度丢失。如刚才的例子中,赋值之后,10.5就变成10了,小数点后面的部分被忽略。

2.强制类型转换不一定能成功,互不相干的类型之间无法强转。

类型转换小结:

  • 不同数字类型的变量之间赋值,表示范围更小的类型能隐式转换成范围较大的类型。
  • 如果需要把范围大的类型赋值给范围小的,需要强制类型转换,但是可能会精度丢失。
  • 将一个字面值常量进行赋值的时候,Java会自动针对数字范围进行检查。

1.13 理解数值提升

int 和 long 混合运算

java 复制代码
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 的运算

java 复制代码
byte a = 10;
byte b = 20;
byte c = a + b;
System.out.println(c);
//编译报错 从int 转换到 byte 可能会有损失

结论:

1.byte 和byte 都是相同类型,但是出现编译报错,原因是,虽然 a 和 b 都是byte,但是计算 a + b 会先将 a 和 b 都提升成 int ,再进行计算,得到的结果也是 int ,将结果赋给 c ,就会出现上述错误。

2.由于计算机的CPU通常是按照4个字节为单位从内存中读写数据,为了硬件上实现方便,诸如byte和short这种低于4个字节的类型,会先提升成 int ,再参与计算。

正确的写法:

java 复制代码
byte a = 10;
byte b = 20;
byte c = (byte)(a + b);
System.out.println(c);

类型提升小结:

  • 不同类型的数据混合运算,范围小的会提升成范围大的。
  • 对于short,byte这种比4个字节小的类型,会先提升成4个字节的 int ,再运算。

1.14 int 和 String 之间的相互转换

int 转成 String

java 复制代码
int num = 10;
//方法一:
String str1 = num + "";
//方法二:
String str2 = String.valueOf(num);

String 转成 int

java 复制代码
String str = "100";
int num = Integer.parseInt(str);

1.15 小结:

  • Java类型汇总,前面的内容重点介绍的是基本数据类型。
  • 每种数据类型及其范围,是需要我们掌握的重点。
  • 隐式类型转换和类型提升,是本节的难点,但是一般我们更推荐在代码中避免不同类型混用的情况,来规避类型转换和类型提升的问题。

2. 运算符

基本四则运算符 + - * /

规则比较简单,值得注意的是除法:

  • int / int 结果还是 int ,需要使用double来计算
java 复制代码
int a = 1;
int b = 2;
System.out.println(a / b);
//结果为0
  • 0不能作为除数
  • %表示取余,不仅可以对 int 求模,也能对double 来求模
java 复制代码
System.out.println(11.5 % 2.0);
//运行结果 1.5

增量赋值运算符+= -= *= /= %=

java 复制代码
int a = 10;
a += 1;//等价于a = a + 1
System.out.println(a);

自增 / 自减运算符++ - -

java 复制代码
int a = 10;
int b = ++a;
System.out.println(b);
int c = a++;
System.out.println(c);

结论:

1.如果不取自增运算的表达式的返回值,则前置自增和后置自增没有区别。

2.如果取表达式的返回值,则前置自增的返回值是自增之后的值,后置自增的返回值是自增之前的值。

2.2 关系运算符

关系运算符主要有六个:==(等于) !=(不等于) < > <=(小于等于) >=(大于等于)

java 复制代码
int a = 10;
int b = 20;
System.out.println(a == b);
System.out.println(a != b);
System.out.println(a > b);
System.out.println(a < b);
System.out.println(a >= b);
System.out.println(a <= b);

注意:

关系运算符的表达式返回值都是boolean 类型。

2.3 逻辑运算符(重点)

逻辑运算符主要有三个:&& || !

注意:

逻辑运算符的操作数(操作数往往是关系运算符的结果)和返回值都是boolean。
逻辑与

规则:两个操作数都为true,结果为true,否则结果为false。

java 复制代码
int a = 10;
int b = 20;
int c = 30;
System.out.println(a < b && b < c);

逻辑或

规则:两个操作数都为false,结果为false,否则结果为true。

java 复制代码
int a = 10;
int b = 20;
int c = 30;
System.out.println(a < b || b < c);

逻辑非

规则:操作数为true,结果为false;操作数为false,结果为true。(这是个单目运算符,只有一个操作数)。

java 复制代码
int a = 10;
int b = 20;
System.out.println(!a < b);

短路求值

&&和 || 遵守短路求值的规则。

java 复制代码
System.out.println(10 > 20 && 10 / 0 == 0);//打印false
System.out.println(10 > 20 || 10 / 0 == 0);//打印true

我们都知道,计算10 / 0会导致程序抛出异常,但是上面的代码却能正常运行,说明10 / 0并没有真正被求值。
结论:

1.对于&&,如果左侧表达式置为false,则表达式的整体一定是false,无需计算右侧表达式。

2.对于||,如果左侧表达式置为true,则表达式的整体一定是true,无需计算右侧表达式。

& 和 |(不推荐使用)

& 和 | 如果操作数为boolean的时候,也表示逻辑运算,但是和&& 以及 || 相比,它们不支持短路求值。

java 复制代码
System.out.println(10 > 20 && 10 / 0 == 0);//程序抛出异常
System.out.println(10 > 20 || 10 / 0 == 0);//程序抛出异常

2.4 位运算符

Java 中对数据操作的最小单位不是字节,而是二进制位。

位运算符主要有4个 & | ~ ^

位操作表示按二进制位运算,计算机中都是使用二级制来表示数据的(0和1构成的序列),按位运算就是在按照二进制位的每一位依次进行计算。
按位与 &: 如果两个二进制位都是 1, 则结果为 1, 否则结果为 0。

举个栗子:

java 复制代码
int a = 10;
int b = 20;
System.out.println(a & b);

进行按位运算, 需要先把 10 和 20 转成二进制, 分别为 1010 和 10100。(我自己记的是:两1为1,有0为0)

按位或 | : 如果两个二进制位都是 0, 则结果为 0, 否则结果为 1。

java 复制代码
int a = 10;
int b = 20;
System.out.println(a | b);

运算方式和按位与相似。(我自己记的是:两0为0,有1为1)。
注意:

当 & 和 | 的操作数为整数(int, short, long, byte) 的时候, 表示按位运算, 当操作数为 boolean 的时候, 表示逻辑运算。
按位取反 ~ : 如果该位为 0 则转为 1, 如果该位为 1 则转为 0.

java 复制代码
int a = 0xf;
System.out.printf("%x\n",~a);

注意:

  1. 0x 前缀数字为十六进制数字,十六进制可以看成是二进制的简化表达式,一个十六进制数字对应4个二进制位。
  2. 0xf 表示10进制的15,也就是二进制的1111.
  3. printf 能够格式化输出内容,%x表示按照十六进制输出。
  4. \n 表示换行符。

2.5 移位运算符(了解)

移位运算符有三个: << >> >>>

都是按照二进制位来运算

**左移 <<: **最左侧位不要了, 最右侧补 0.

java 复制代码
int a = 0x10;
System.out.printf("%x\n",a << 1);

**右移 >>: **最右侧位不要了, 最左侧补符号位(正数补0, 负数补1)
无符号右移 >>>: 最右侧位不要了, 最左侧补 0
注意:

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

2.6 条件运算符

条件运算符只有一个: 表达式1 ? 表达式2 : 表达式3

当表达式1 的值为 true 时, 整个表达式的值为表达式2的值; 当表达式1的值为 false 时, 整个表达式的值为表达式3的值.

也就是:当表达式1的值为真时,执行表达式2,为假时执行表达式3.

也是 Java 中唯一的一个 三目运算符, 是条件判断语句的简化写法.

java 复制代码
//求两个整数的最大值
int a = 10;
int b = 20;
int max = a > b ? a : b;

2.7 运算符的优先级

先看一段代码:

java 复制代码
System.out.println(1 + 2 * 3);

结果为7,说明先计算了2*3,再计算+1

运算符之间是有优先级的,具体的规则我们不用刻意去记,在可能存在歧义的代码中加上括号即可。

2.8 小结:

  1. % 操作再 Java 中也能针对 double 来计算.
  2. 需要区分清楚 前置自增 和 后置自增之间的区别.
  3. 由于 Java 是强类型语言, 因此对于类型检查较严格, 因此像 && 之类的运算操作数必须是 boolean.
  4. 要区分清楚 & 和 | 什么时候是表示按位运算, 什么时候表示逻辑运算
    整体来看,Java的运算符的基本规则和C语言基本一致。

3. 注释

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

单行注释:// 注释内容(用的最多)

多行注释:/* 注释内容*/(不推荐)

文档注释: /** 文档注释 */(常见于方法和类之上描述方法和类的作用),可用来自动生成文档

3.2 注释规范

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

4. 关键字

关键字是Java中一些具有特定含义的单词

用于定义访问权限修饰符的关键字 private protected public
用于定义类,函数,变量修饰符的关键字 abstract final static synchronized
用于定义类与类之间关系的关键字 extends implements
用于定义建立实例及引用实例,判断实例的关键字 new this super instanceof
用于异常处理的关键字 try catch finally throw throws
用于包的关键字 package import
用于修饰符关键字 native strictfp transient volatile assert

定义的变量名不能和关键字冲突

相关推荐
只想摆烂@10 分钟前
C# 如何单纯的优化循环
开发语言·c#
王会举16 分钟前
Java实现日志全链路追踪.精确到一次请求的全部流程
java·log4j
马剑威(威哥爱编程)29 分钟前
使用 Mybatis 时,调用 DAO接口时是怎么调用到 SQL 的?
java·sql·mybatis
阑梦清川36 分钟前
C++多态~~的两个特殊情况
开发语言·c++
白骑士所长41 分钟前
白骑士的C语言教学基础篇 1.3 控制流
c语言·开发语言
EQ-雪梨蛋花汤1 小时前
使用docfx生成API文档【生成c#帮助文档】
开发语言·c#
铁匠匠匠1 小时前
django学习入门系列之第三点《案例 小米商城二级菜单》
前端·css·经验分享·python·学习·django·前端框架
三村阿明1 小时前
Java多线程
java·开发语言·多线程·reentrantlock
鸿运当头,财源广进1 小时前
【系统规划与管理师读书笔记】第二章 信息技术知识
经验分享·职场和发展
Ephemeroptera1 小时前
IT专业入门,高考假期预习指南
java·c语言·网络·python·高考