前言:
本篇博客紧接着上一篇博客的基本数据类型,以及变量的内容,继续学习运算符和关键字,以及注释等细节的内容。
每文一图:
继续开始学习吧!
运算符和关键字:- 一.运算符
- 1.算术运算符
- 2.关系运算符
- 3.逻辑运算符(重点)
- ① 逻辑与 &&
- ②逻辑或 ||
- ③逻辑非 !
- ④短路求值
- 4. 位运算符
- ①按位与 &
- ②按位或 |
- ③按位取反 ~:
- ④ 按位异或 ^
- 5.移位运算
- ① 左移 <<
- ② 右移 >>
- ③ 无符号右移 >>>
- 6.条件运算符
- 7.小细节补充
- 二.注释
- 1.基本规则
- 2.注释规范
- 三.关键字
学完类型,那当然要学习他们之间的计算,是不是很想小学学习的顺序,没错,万变不离其宗,我们要从基础开始学起。开始肝!
1.算术运算符首先肯定是简单的运算符,算术运算符。
基本四则运算符 + - * / %
对于算术运算符,规则比较简单,跟正常的加减乘除基本没差,我们来看看有差别的和需要注意的一些点:
1.int / int 结果还是 int, 如果需要保留小数部分需要使用 double 来计算。
如:
public static void main(String[] args) {
int a = 1;
int b = 2;
System.out.println(a / b);
// 结果为 0
}
2.0 不能作为除数,如果使用0作为除数会报错。
如:
public static void main(String[] args) {
int a = 1;
int b = 0;
System.out.println(a / b);
//运行: ArithmeticException: / by zero //错误信息
}
3.% 表示取余, 不仅仅可以对 int 求模, 也能对 double 来求模。
这里的%是取余的意思,也就是得到整除后剩下的余数的意思,比如a=9,b=5,a%b的结果就是4。小数也一样是:
public static void main(String[] args) {
System.out.println(11.5 % 2.0);
//运行结果 1.5
}
4.增量赋值运算符 += -= *= /= %=
对于这几个运算符,他们还会玩花的,组合起来,但是其实就是表达得更流畅一点,没有上面特别的要求。
比如:
public static void main(String[] args) {
int a = 10;
int b = 5;
int c = 2;
a += 1; // 等价于 a = a + 1
System.out.println(a);
b -= 2;// 等价于 b = b - 2
System.out.println(b);
c *= 5;// 等价于 c = c * 5
System.out.println(c);
//结果: 11 3 10
}
5.自增/自减运算符 ++ --
对于+和-号,还有自增/自减运算符 ++ --,++表达的意思就是加1,–表达的就是减1,但是,当他们放在不同的位置的时候,就会产生不同的作用。
如:
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = ++a;
System.out.println("a:"+a+" c:"+c);
int d = b++;
System.out.println("b:"+b+" d:"+d);
//a:11 c:11
//b:21 d:20
}
同学们有没有看出什么不同,其实就在于++或者–是在变量前还是变量后,这就是前置++后置++或者前置–后置–的区别了:
对于前置++或者–,是对变量先进行++或者–的操作,再运行其他语句,比如赋值。而对于后置++或者–,是先运行其他语句,最后再进行++或者–。
也就是说,上面的a和c在int c = ++a;的语句之后,都变成了11,就是说明a是先本身++,然后再赋值。而b和d不一样,b是先赋值再++,所以b是21而d是20。
结论:
- 如果不取自增运算的表达式的返回值, 则前置自增和后置自增没有区别。
- 如果取表达式的返回值, 则前置自增的返回值是自增之后的值, 后置自增的返回值是自增之前的值。
2.关系运算符
关系运算符主要有六个:
== != < > <= >=
在这里也简单的用代码介绍一下:
public static void main(String[] args) {
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
}
对于关系运算符,在Java中,想表示两个数相等要用==,单一个=是表示赋值的意思,将右值赋给左值。而想表达不等于的意思的时候,就需要用!=,还有另外的几个就是正常运算,大于小于,大于或等于,小于或等于。
对于我们上面的代码,就是输出一种判断,正确就会输出true,错误就是false。
注意: 关系运算符的表达式返回值都是boolean 类型!
3.逻辑运算符(重点)
逻辑运算符主要有三个:
&& || !
这里是比较重要的三个运算符,我们挨个来理解:
① 逻辑与 &&规则: 两个操作数都为 true, 结果为 true, 否则结果为 false。
比如:
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = 30;
System.out.println(a < b && b < c);
//输出 true
System.out.println(a < b && b > c);
//输出 false
}
②逻辑或 ||
规则: 两个操作数都为 false, 结果为 false, 否则结果为 true。
比如:
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = 30;
System.out.println(a > b || b > c);
//输出 false
System.out.println(a > b || b < c);
//输出 true
}
③逻辑非 !
规则: 操作数为 true, 结果为 false; 操作数为 false, 结果为 true(这是个单目运算符, 只有一个操作数)。
如:
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(!(a < b));
//输出 false
}
④短路求值
&& 和 || 遵守短路求值的规则
public static void main(String[] args) {
System.out.println(10 > 20 && 10 / 0 == 0); // 打印 false
System.out.println(10 < 20 || 10 / 0 == 0); // 打印 true
}
在前面的学习我们知道, 计算 10 / 0 会导致程序抛出异常.,但是上面的代码却能正常运行, 说明 10 / 0 并没有真正被求值。所以,我们有如下结论:
- 对于 && , 如果左侧表达式值为 false, 则表达式的整体的值一定是 false, 无需计算右侧表达式。
- 对于 ||, 如果左侧表达式值为 true, 则表达式的整体的值一定是 true, 无需计算右侧表达式。
4. 位运算符
Java 中对数据的操作的最小单位不是字节, 而是二进制位其中位运算就是在二进制中做文章。而对于位运算符主要有四个:
& | ~ ^
位操作表示按二进制位运算。计算机中都是使用二进制来表示数据的(01构成的序列), 按位运算就是在按照二进制位的每一位依次进行计算。
我们来挨个学习:
①按位与 &如果两个二进制位都是 1, 则结果为 1, 否则结果为 0。
比如下面的代码:
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(a & b);
//结果为0
}
怎么算的呢?我们来图解一下:
实际上就是化为二进制进行一种计算。
②按位或 |
如果两个二进制位都是 0, 则结果为 0, 否则结果为 1。
对于按位或也是一样,但它的运算规则是有1则1,全0才为0。比如:
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(a | b);
}
同样我们弄一个简单的图解:
还有一点需要注意的是:注意: 当 & 和 | 的操作数为整数(int, short, long, byte) 的时候, 表示按位运算, 当操作数为 boolean 的时候, 表示逻辑
运算,比如a & b,ab都是整数就是按位运算,ab都是布尔就是逻辑运算。
③按位取反 ~:
如果该位为 0 则转为 1, 如果该位为 1 则转为 0。
这里的例子我们举特别一点,顺便普及一下进制的知识:
public static void main(String[] args) {
int a = 0xf;
System.out.printf("%xn", ~a);
//输出 ffff fff0
}
在这里,0x表示十六进制表示数,在十六进制中,除了1-9,就是以英文字母表示的11(a),12(b)…15(f)。因为一个f占的就是4个二进制位,所以对于这里的a来说,表示为十六进制真正的样子是00 00 00 0f,所以按位取反之后得到的就是ff ff ff f0了。注意这里为了更清楚才打的空格,实际上数字是连续的。
对于上面的代码需要注意的是:
- 0x 前缀的数字为 十六进制 数字. 十六进制可以看成是二进制的简化表示方式. 一个十六进制数字对应4个二进制位。
- 0xf 表示10进制的15, 也就是二进制的1111。
- printf 能够格式化输出内容, %x表示按照十六进制输出。
- n 表示换行符。
进制:
而对于进制,我们常用的有二进制,十进制,十六进制,还有偶尔会出现的八进制。二进制就是010010这种,十进制大家都会,十六进制就是0ff05这种,只是多了abcdef这几位表示。
那么他们之间的互相转化,我们可以通过十进制作为跳板,这样能清晰的计算出来,比如01100001转换成十进制是97,然后十进制转化为十六进制,得到的就是61。
是不是觉得61很奇怪,实际上对于十六进制我们需要这样理解,是6*(16^1)+1*(16^0),每一个位都是这个位上的数乘以十六的n-1次方。n表示这个位的位置。
④ 按位异或 ^
如果两个数字的二进制位相同, 则结果为 0, 相异则结果为 1。
对于按位异或 ,也是十分有用的一个运算符,我们来看一下:
public static void main(String[] args) {
int a = 5;
int b = 3;
System.out.printf("%dn", a ^ b);
//a 0101
//b 0011
//打印0110,也就是6
}
对于按位异或,我们可以做一些比较有意思的代码,比如在一个数组中除了一个数字出现过一次,其他都出现过两次,要找到这个数字,就可以用按位异或,因为出现两次的数字按位异或就会我消我自己,剩下的就是只出现一次的数字了。
题目:一个数组中的所有元素都出现了两次,只有一个元素出现了一次,找到这个元素并输出。
参考代码:
//暂时理解即可
public static void main(String[] args) {
int[] array = {1,2,3,2,1};
int sum = array[0];
for (int i = 1;i < array.length;i++) {
sum = sum ^ array[i];
//^上之后相同的互相消为0
}
System.out.println(sum);
}
5.移位运算
移位运算符有三个,同样是在二进制里做文章:
<< >> >>>
我们来接个看一下:
① 左移 <<最左侧位不要了, 最右侧补 0。
比如说:
再比如:
public static void main(String[] args) {
int a = 0x10;
System.out.printf("%xn", a << 1);
// 运行结果(注意, 是按十六进制打印的) 20
}
② 右移 >>
最右侧位不要了, 最左侧补符号位(正数补0, 负数补1)
右移和左移差不多,但是有所区别,右移也是切掉右边的一位,然后在最左侧补符号位,但是因为这里有正负数之分,所以去掉之后需要看正负再补。
比如:
public static void main(String[] args) {
int a = 0x10;
System.out.printf("%xn", a >> 1);
// 运行结果(注意, 是按十六进制打印的) 8
}
③ 无符号右移 >>>
最右侧位不要了, 最左侧补 0
对于一些特殊的要求,需要无论正负数都补的是0,就有无符号右移,对于无符号右移,就是比正常右移多了一个>,也是和右移一样使用的。
比如:
public static void main(String[] args) {
int a = 0xffffffff;
System.out.printf("%xn", a >>> 1);
// 运行结果(注意, 是按十六进制打印的) 7fffffff
}
对于移位运算需要注意的事项有:
- 左移 1 位, 相当于原数字 * 2. 左移 N 位, 相当于原数字 * 2 的N次方。
- 右移 1 位, 相当于原数字 / 2. 右移 N 位, 相当于原数字 / 2 的N次方。
- 由于计算机计算移位效率高于计算乘除, 当某个代码正好乘除 2 的N次方的时候可以用移位运算代替。
- 移动负数位或者移位位数过大都没有意义。
6.条件运算符
条件运算符只有一个,也比较简单容易理解,它的表达式为:
表达式1 ? 表达式2 : 表达式3
它的含义为:当 表达式1 的值为 true 时, 整个表达式的值为 表达式2 的值; 当 表达式1 的值为 false 时, 整个表达式的值为 表达式3 的值。
条件运算符也是 Java 中唯一的一个 三目运算符, 是条件判断语句的简化写法。
例子:
public static void main(String[] args) {
// 求两个整数的最大值
int a = 10;
int b = 20;
int max = a > b ? a : b;
//这里表示的就是 a大于b吗,大于返回a,小于返回b
//
}
条件运算符可以让我们更方便的判断简单的东西,合理运用可以有很好的效果。
7.小细节补充
先看一段代码:
public static void main(String[] args) {
System.out.println(1 + 2 * 3);
//7 先计算了 2*3 , 再计算 1+
System.out.println(10 < 20 && 20 < 30);
//先计算的 10 < 20 和 20 < 30, 再计算 &&. 否则 20 && 20 这样的操作是语法上有误的
}
这两个代码表明,其实运算符是有优先级的,就好像我们平时数学中先乘除后加减,但是对于运算符的优先级,其实也不需要太过记忆,我们需要哪边先运算,可以直接加上括号,便可以了。
运算符之间是有优先级的. 具体的规则我们不必记忆. 在可能存在歧义的代码中加上括号即可。
以及下面的一些小细节:
1.% 操作再 Java 中也能针对 double 来计算.
2.需要区分清楚 前置自增 和 后置自增之间的区别.
3.由于 Java 是强类型语言, 因此对于类型检查较严格, 因此像 && 之类的运算操作数必须是 boolean.
4.要区分清楚 & 和 | 什么时候是表示按位运算, 什么时候表示逻辑运算
二.注释
注释是为了让代码更容易被读懂而附加的描述信息. 不参与编译运行, 但是却非常重要.时刻牢记! 代码写出来是为了给人看的, 更是为了给三个月后的你自己看的!我们能从以前学习到东西。
那么注释有什么特别需要呢,我们来看一下:
1.基本规则Java中的注释主要分为以下三种:
1.单行注释:// 注释内容(用的最多)
2.多行注释:(不推荐)
3.文档注释: (常见于方法和类之上描述方法和类的作用),可用来自动生成文档
一般来说,我们都是用的单行注释,既方便又清晰,对于多行注释,因为其中直接屏蔽了一块内容,所以用的不多,一般用于对代码注销。
public static void main(String[] args) {
System.out.println(1 + 2 * 3);
//7 先计算了 2*3 , 再计算 1+
//单行注释,方便理解
}
public static void main(String[] args) {
System.out.println(1 + 2 * 3);
//7 先计算了 2*3 , 再计算 1+
}
//块注释,多用于注释代码
2.注释规范
对于注释,也有软性指标,对于注释我们应该遵守的一些规则:
1.内容准确: 注释内容要和代码一致, 匹配, 并在代码修改时及时更新。
内容一定要准确,不要注释乱写什么今天天气晴转多云,我感觉还行,中文吃了酸菜鱼什么的。要正确写好,该注释的东西。
2.篇幅合理: 注释既不应该太精简, 也不应该长篇大论。
对于注释,应该尽量控制好幅度,太过简单的不如不注释,看了也没弄懂的那还注释啥,也不要太长,一长起来看后面代码就没那么连贯了。
3.使用中文: 一般中国公司都要求使用中文写注释, 外企另当别论.
不要说用的是英文的IDEA,要有范把注释也弄成英文的,一般来说我们都同中文作为注释。
4.积极向上: 注释中不要包含负能量。
三.关键字
关键字是 Java 中的一些具有特定含义的单词。也是我们在创建变量的时候不能作为变量名的单词。
作为关键字要说的有很多,因为本身关键字就挺多的,这里就简单的叙述一下,后面再有文章对于关键字陆续学习。
对于关键字,我们可以将其重要的分类为以下:
然后每一个关键字的意思在下表中有,具体的使用请期待博主后面的文章噢。
| 关键字 | 含义 |
|---|---|
| abstract | 表明类或者成员方法具有抽象属性 |
| assert | 断言,用来进行程序调试 |
| boolean | 基本数据类型之一,声明布尔类型的关键字 |
| break | 提前跳出一个块 |
| byte | 基本数据类型之一,字节类型 |
| case | 用在switch语句之中,表示其中的一个分支 |
| catch | 用在异常处理中,用来捕捉异常 |
| char | 基本数据类型之一,字符类型 |
| class | 声明一个类 |
| const | 保留关键字,没有具体含义 |
| continue | 回到一个块的开始处 |
| default | 默认,例如,用在switch语句中,表明一个默认的分支 |
| do | 用在do-while循环结构中 |
| double | 基本数据类型之一,双精度浮点数类型 |
| else | 用在条件语句中,表明当条件不成立时的分支 |
| enum | 枚举 |
| extends | 表明一个类型是另一个类型的子类型,这里常见的类型有类和接口 |
| final | 用来说明最终属性,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变,用来定义常量 |
| finally | 用于处理异常情况,用来声明一个基本肯定会被执行到的语句块 |
| float | 基本数据类型之一,单精度浮点数类型 |
| for | 一种循环结构的引导词 |
| goto | 保留关键字,没有具体含义 |
| if | 条件语句的引导词 |
| implements | 表明一个类实现了给定的接口 |
| import | 表明要访问指定的类或包 |
| instanceof | 用来测试一个对象是否是指定类型的实例对象 |
| int | 基本数据类型之一,整数类型 |
| interface | 接口 |
| long | 基本数据类型之一,长整数类型 |
| native | 用来声明一个方法是由与计算机相关的语言(如C/C++/FORTRAN语言)实现的 |
| new | 用来创建新实例对象 |
| package | 包 |
| private | 一种访问控制方式:私用模式 |
| protected | 一种访问控制方式:保护模式 |
| public | 一种访问控制方式:共用模式 |
| return | 从成员方法中返回数据 |
| short | 基本数据类型之一,短整数类型 |
| static | 表明具有静态属性 |
| strictfp | 用来声明FP_strict(单精度或双精度浮点数)表达式遵循IEEE 754算术规范 |
| super | 表明当前对象的父类型的引用或者父类型的构造方法 |
| switch | 分支语句结构的引导词 |
| synchronized | 表明一段代码需要同步执行 |
| this | 指向当前实例对象的引用 |
| throw | 抛出一个异常 |
| throws | 声明在当前定义的成员方法中所有需要抛出的异常 |
| transient | 声明不用序列化的成员域 |
| try | 尝试一个可能抛出异常的程序块 |
| void | 声明当前成员方法没有返回值 |
| volatile | 表明两个或者多个变量必须同步地发生变化 |
| while | 用在循环结构中 |
——该表资料来自百度百科。
这就是本篇运算符和关键字的全部内容啦,如果觉得还不错或者感觉对你有帮助,不妨点赞关注一键三连,一起学习,共同努力!也可以期待这个系列接下来的博客噢。
链接:都在这里! Java SE 带你从零到一系列
还有一件事:



