#:个人学习java的笔记记录,参考课程为:001-课程内容介绍_哔哩哔哩_bilibili
本文适合有一定c语言基础,没有java基础的同学。因此一些与c差别不大的地方不会着重介绍
一 几个量之间的辨析
1. 标识符
在Java中,标识符是用来给变量、方法、类和包等命名的字符序列。(程序员用来给自己变量起名字用的)
标识符可以用来标识几乎一切允许程序员起名字的东西(如:变量名 方法名 类名、接口名、枚举名、注解名 包名 常量名)
1.1 标识符命名规则:(强制要求的)
标识符可以由字母、数字、下划线(_)和美元符号($)组成,不能含有其他符号。(但是标识符不能以数字开头)——值得注意的是java适配全世界语言系统,因此这里的字母指的是各种语言
标识符不可以是java关键字or保留字‘且标识符区分大小写。
1.2 标识符命名规范:(非强制要求的,行业规范)
均要求 简洁见名知意 和 驼峰命名法(即整体小写但是每个单词的首字母大写)
具体要求如下:
a.类名、接口名、枚举、注解:首字母大写,后面每个单词首字母大写。(StudentService)
b.变量名和方法名:首字母小写,后面每个单词首字母大写。(doSome,doOther)
c.常量名:全部大写,每个单词用下划线连接。(LOGIN_SUCCESS,SYSTEM_ERROR)
d.包名:全部小写
2.关键字:
Java关键字是Java编程语言中预定义的具有特殊含义的单词,这些单词不能被用作标识符,而是在语法中有特定的用法和限制。(即在java创立之初,就设定了这些词有特殊的含义,把他们占用了,我们不能使用)
2.1 常见的关键字(Java关键字都是小写的)
这些不用特意去记,慢慢地就会学到了
关键字:abstract, assert, boolean, break, byte, case, catch, char, class, continue, default, do, double, else, enum, extends, final, finally, float, for, if, implements, import, instanceof, int, interface, long, native, new, package, private, protected, public, return, short, static, strictfp, super, switch, synchronized, this, throw, throws, transient, try, void, volatile, while
Java保留字:goto,const
(保留字即java开发之初并没有把它作为关键字使用,但是考虑到日后可能要用到,因此将这两个词保留了下来)
三.字面量:
字面量指的是在程序中直接使用的各种数据。
java中字面量有以下几种:这些后面都会有所介绍
a.整数型:10、-5、0、100
b.浮点型:3.14、-0.5、1.0
c.布尔型:true、false
d.字符型:'a'、'b'、'c'、'1'、'2'、'国'
e.字符串型:"Hello"、"World"、"Java"
四.变量:
变量是内存中的一块空间,是计算机中存储数据最基本的单元。
1变量三要素:
数据类型(决定空间大小)【int, double, String】
变量名(只要是合法的标识符即可)
变量值(变量中具体存储的数据)
2变量作用域
变量的作用域即变量的有效范围(变量所处的那个大括号)
作用域的不同主要是因为声明在不同位置的变量具有不同的生命周期。所谓的生命周期是:从内存开辟到内存释放。
3变量分类
分为三类,如下:
public class Main {
public static void main(String[] args) {
//局部变量:在方法体中定义的变量,即局部变量(它只在当前大括号内有效)
int a = 1;
}
//在类体中定义的变量都是成员变量,其中又分为实例变量和静态变量
//这种普通的即使实例变量
int b = 0;
//如果前面有static修饰符,则是静态变量
static int c = 0;
}
五.数据类型
关于默认值:Java语言中变量必须先声明,再赋值,才能使用。对于局部变量来说必须手动赋值,而对于成员变量来说,如果没有手动赋值,系统会自动赋默认值
1整数型
整数型虽然有四种,但是在实际使用中,我们往往只使用其中的int和long。
且Java中整数型字面量默认被当做int类型来处理,如果要表示long类型的整数,需要在字面量后面加上'L'或'l'标记。(为了便于与数字1进行区分,一般都是用L表示long类型)
eg:
long d = 2147487892;
// 会报错: 整数太大(不是long存不下。)
// 原因是:2147487892默认被当做int来处理,分配4个字节。4个字节本身是无法存储2147483648
// 解决方法:在其后面添加一个L即可
1.1类型转换
自动类型转换:在Java中,对于基本数据类型来说,小容量是可以直接赋值给大容量的,这被称为自动类型转换。在运算中,两个不同数字类型的运算结果也会是其中范围大的那个(对于数字类型来说大小关系为:byte < short < int < long < float < double)
强制类型转换:java中大容量是无法直接转化成小容量的,系统把这个权限给到了程序员。强制类型转换的本质/底层原理是在转换时砍掉左侧多余的二进制。这就有可能导致精度损失
1.2short和byte类型的特殊用法
在Java中有这样一个规定,当整数型字面量没有超出byte的范围:可以直接赋值给byte类型的变量。
byte b = 127; // 这是允许的
而其中short也是同理的。
2浮点数类型
Java中,浮点型字面量默认被当做double类型,如果要当做float类型,需要在数字后面添加 F 或 f。
float f = 3.0;
// 编译报错 报错原因是:3.0默认被当做double类型,大容量无法直接赋值给小容量。
float f = 3.0F;//这才是正确的写法
这一点和整数数据类型是一样的
2.1浮点数的两种表示形式
第一种形式:十进制 double x = 1.23; double y = 0.23; double z = .23;
第二种形式:科学计数法
double x = 0.123E2; // 0.123 * 10的平方
double y = 123.34E-2; // 123.34 / 10的平方
2.2浮点数的比较问题
一旦有浮点数参与的运算比较,都不能直接使用==去与其他数据进行比较,这是因为浮点数存在精度问题,不能直接比较相等。正确的做法应该是让两个浮点数相减后与一个极小的数比较,若比这个极小的数还小,则可以视为相等。
if(z - 2.3 < 0.000001)
如上图才是浮点数比较的正确方法
3.字符型char
符号表示一定是用单引号括起来,只能表示单个字符(也可以是一个汉字)
3.1关于空字符
char c = ‘’; 这是不允许的
char c = ‘\u0000’; 这表示一个空字符,也是char的默认值。其中\u0000是一个Unicode码。 空字符与空格字符是不同的。
空字符表示什么也没有。空格字符表示一个空格。
3.2转义字符的使用
a.可以用来表示一些操作
\t: 表示制表符,相当于按下 Tab 键
\n: 表示换行符
b.使用\表示后面一个字符会正常表示(注意:只限紧挨在后面的那一个字符)
\": 表示双引号(") \': 表示单引号(') \\: 表示反斜线(\)本身
4.布尔类型
boolean类型只有两个值:true、false。没有其它值,没有0和1这一说。
这一点和c差别较大, 不能用1和0去表示逻辑判断。
六.运算符
此处只介绍与c语言不同的运算符:
1.逻辑运算符
逻辑运算符两边的操作数要求必须是布尔类型,并且最终运算结果也一定是布尔类型。(且要注意,java中的布尔类型只限于ture和flase)
1.1&,|与&&,||的区别
区别在于&&和||会存在短路现象,优点是可以优化内存,加快速度,缺点是右边的操作数是不会进行的(因此一般采取&&,||)
a.
逻辑与&:两边操作数都是true,结果才是true。可以翻译为“并且”。
逻辑或|:两边操作数只要有一个是true,结果就是true。可以翻译为“或者”
b.
短路与&&:和逻辑与&的运算结果相同。只是存在一种短路现象。(左边操作数为false时,右边操作数不执行)
短路或||:和逻辑或|的运算结果相同。只是存在一种短路现象。(左边操作数为true时,右边操作数不执行)
2.按位运算符
按位运算符主要用于在二进制层面上对整数进行处理,优点是运算的效率会比普通方法更高;要求按位运算符的操作数必须要是整数
以下为常见的七种位运算符:
左移 << 右移 >> 无符号右移 >>>
按位与 & 按位或 | 按位异或 ^ 按位取反 ~
注:计算机中的一切数据操作,都是对补码就行操作,因此我们分析时都要转成补码。
2.1左移运算符<<
即将一个二进制数的所有位向左移动指定的位数。
作用是:相当于将数值乘以2的n次方 且 不会变换正负号。(左移的过程中,会对溢出进行截断)
/*
原码:00000000 00000000 00000000 10000000
反码:00000000 00000000 00000000 10000000
补码: 00000000 00000000 00000000 10000000
左移2位:000000 00000000 00000000 1000000000
*/
int b = 128;
System.out.println(b << 2); // 512(128 * 2的2次方)
/*
原码:10000000 00000000 00000000 01100100
反码:11111111 11111111 11111111 10011011
补码: 11111111 11111111 11111111 10011100
左移2位:111111 11111111 11111111 1001110000(补码)
原码: 100000 00000000 00000000 0110010000
*/
int c = -100;
System.out.println(c << 2); // -400(-100 * 2的2次方)
2.2右移运算符>>
即将一个二进制数的所有位向右移动指定的位数。
作用是:相当于将数值除以2的n次方 且 不会变换正负号。(右移的过程中,会对溢出进行截断)。对于正数负数和0,他的处理不同,具体如下:
对于正数,符号位不变,右移时左补0
对于负数,符号位不变,右移时左补1。
对于零,右移运算符操作后结果仍为零。
/*
原码:00000000 00000000 00000000 00000001
反码:00000000 00000000 00000000 00000001
补码: 00000000 00000000 00000000 00000001
右移1位:000000000 00000000 00000000 0000000
*/
int a = 1;
System.out.println(a >> 1); // 0
/*
00000000 00000000 0000000 10000000
000000000000 00000000 0000000 1000
*/
int b = 128;
System.out.println(b >> 4); // 8
/*
原码:10000000 00000000 00000000 10000000
反码:11111111 11111111 11111111 01111111
补码:11111111 11111111 11111111 10000000
右移:111111111111 11111111 11111111 1000(补码)
原码:100000000000 00000000 00000000 1000
*/
int c = -128;
System.out.println(c >> 4); // -8
值得注意的是1比较特殊,经过分析不难发现1右移一位后会直接变成0
2.3无符号右移运算符>>>
将一个二进制数的所有位向右移动指定的位数 且 不考虑符号位。
作用是:相当于将数值除以2的n次方 且 将最高位固定填充为0。(右移的过程中,会对溢出进行截断)。
因为最高位固定填充为0,因此最后的结果一定会是0或者正数。
2.4按位与&
将两个整数的二进制表示按位进行与运算,只有当相应的二进制位都为1时,结果才为1,否则结果为0
// 00100011
int a = 35;
// 00011010
int b = 26;
/*
00100011
& 00011010
-------------------
00000010
*/
System.out.println(a & b); // 2
应用:可以用来判断一个数是否为奇数(更快速)
/*
怎么判断一个数字是否为奇数?
第一种方式:对2取模,结果不等于0,表示奇数。
第二种方式:让这个数字和1进行按位与操作,结果是1,表示是奇数。
*/
int num = 35;
if(num % 2 != 0){
System.out.println(num + "是奇数");
}
/*
00100011
& 00000001
-------------
00000001
*/
if((num & 1) == 1){ // 注意运算符优先级问题。
System.out.println(num + "是奇数");
}
2.5按位或|
将两个整数的二进制表示按位进行或运算,只有当相应的二进制位都为0时,结果才为0,否则结果为1
// 00100011
int a = 35;
// 00011011
int b = 27;
/*
00100011
| 00011011
----------------
00111011
*/
System.out.println(a | b); // 59
应用:可以用来设置标志位(即让一个数的二进制形式某位设置为0或者1)
/*
具体应用:设置标志位。(按位或的具体应用。)
将0这个数字的二进制位低位第4个二进制位设置为1.
*/
int flag = 0;
flag = flag | (1 << 3);
System.out.println(flag); // 8
2.6按位异或^
将两个整数的二进制表示按位进行异或运算,只有当相应的二进制位不同,结果才为1,否则结果为0
// 00001010
int a = 10;
// 00000011
int b = 3;
/*
00001010
^ 00000011
------------------
00001001
*/
System.out.println(a ^ b); // 9
/*
00001001
^ 00000011
----------------
00001010
*/
System.out.println(a ^ b ^ b); // 10
应用:可以用来加密和解密——这应用的是自反性(即如果a^b,b再次^a后;结果仍是a)
/*
具体应用:加密解密
*/
int data = 2147483647; // 原始数据,这个数据将来要进行加密的。
// 对以上的data进行加密
// 秘钥(私人的,只有我知道这个钥匙)
int key = 483;
// 加密
int password = data ^ key;
System.out.println(password); // 2147483164
// 解密
int num = password ^ key;
System.out.println(num);
2.7取反操作~
将整数的二进制表示按位进行取反运算,即0变为1,1变为0
// 00000000 00000000 00000000 00001010
int a = 10;
/*
取反:
11111111 11111111 11111111 11110101(补码)
10000000 00000000 00000000 00001011(原码)
*/
System.out.println(~a); // -11
应用:位清除操作(即可以将某个二进制位中指定位清除为0)
/*
按位取反的具体应用:将某个二进制位清0
*/
int value = 0b1111111111; // 待清0的数据(将低位第4个清0)
int flag = (1 << 3);
// 11111111 11111111 11111111 11110111
//&00000000 00000000 00000011 11111111
//-------------------------------------
// 00000000 00000000 00000011 11110111
value = value & (~flag);
System.out.println(value);
System.out.println(0b1111110111);
3.赋值运算符
3.1基本赋值运算符
= 等号右边先执行,将直接结果赋值给左边的变量
3.2扩展赋值运算符
+=、-=、*=、/=、%=、&=、|=、^=、>>=、<<=、>>>=
要注意:扩展赋值运算符不会改变运算结果的类型。(即使精度损失了,也不会改变运算结果类型。)
4.条件运算符
是一个三目运算符
4.1语法格式:
布尔表达式 ? 表达式1 : 表达式2
4.2运算原理:
当布尔表达式结果是true的时候,将表达式1的执行结果作为整个表达式的执行结果。
当布尔表达式结果是false的时候,将表达式2的执行结果作为整个表达式的执行结果。
/*
请使用三目运算符完成两个数字中较大数字的筛选。
*/
int a = 300;
int b = 200;
System.out.println(a > b ? a : b);
七.控制语句
1.switch的辨析:
a. switch 语句适用于判断固定值。if语句适用于判断范围或区间时使用。switch能做的if肯定能做,if能完成的switch不一定能完成。
b. JDK7之前,switch只支持int类型、枚举类型,在JDK7之后,增加了对字符串类型的支持。
c. case 语句中的值必须是字面量,不能是变量;且 case 语句中的值必须和switch后面的值是同一类型,或者能够相互转换。
d. case可以合并。
e. 在每个 case 分支中要加上 break 语句,以避免case穿透现象。(即从一个case进去后,会接着运行后面的所有代码
f. 在 switch 语句中,一般都应该有一个 default 分支,用于处理一些特殊情况,以避免程序出错。 (当然,default语句不写,也不会编译报错。)
g. switch 语句中的 default 分支可以放在 switch 块的任意位置,但是通常建议将 default 分支放在所有 case 分支的最后面。(可读性好)
switch(oper){
case "+":
result = num1 + num2;
break;
case "-":
result = num1 - num2;
break;
case "*":
result = num1 * num2;
break;
case "/":
result = num1 / num2;
break;
case "%":
result = num1 % num2;
break;
default :
System.out.println("不支持此运算!");
return;
}
System.out.println(num1 + oper + num2 + "=" + result);
2.java12新特性
Java12中switch引入了新特性,代码变得更加简洁:
switch(x){
case 1 -> System.out.println(1);
case 2 -> System.out.println(2);
default -> System.out.println("default");
}
switch(x){
case 1, 2, 3 -> System.out.println("123");
}
switch(x){
case 1 -> {
System.out.println(1);
System.out.println(1);
}
}