第二章 基本语法
1.关键字和保留字
1.1关键字
定义:被java语言f赋予了特殊含义,用作专门用途的字符串
特点:关键字中所有的字母都是小写
用于定义 | 数据类型 | 的关键字 | ||
---|---|---|---|---|
class | interface | enum | byte | short |
int | long | float | double | char |
boolean | void | |||
用于定义 | 流程控制 | 的关键字 | ||
if | else | switch | case | default |
while | do | for | break | continue |
return | ||||
用于定义 | 访问权限 | 修饰符的 | 关键字 | |
private | protected | public |
用于定义类 | 函数、变量 | 的关键字 | ||
---|---|---|---|---|
abstract | final | static | synchronized | |
用于定义 | 简历实例 | 引用实例 | 的关键字 | |
new | this | super | instanceof | |
用于处理 | 异常的 | 关键字 | ||
try | catch | finally | throw | throws |
用于包的 | 关键字 | |||
package | import | |||
其他修饰 | 符的关键 | 字 | ||
native | strictfp | transient | volatile | assert |
用于定义 | 数据类型 | 值的字面值 | ||
true | false | null |
1.2保留字
定义:现有的java版本尚未使用,但是以后的版本可能会作为关键字使用,自己命名标识符的时候要避免使用关键字和保留字。
goto、const
2.标识符
标识符:凡是自己可以起名字的地方都可以叫标识符
比如:类名、变量名、方法名、接口名、包名…
2.1标识符的命名规则:
-
由英文字母大小写,数字0-9、_或$组成,其中数字不可以开头
不可以使用关键字和保留字,但是可以包含
-
java中严格区分大小写,长度无限制,不可包含空格
-
java中的名称的命名规范
-
包名:多单词组成是所有字母都要小写 xxyyyzzz
-
类名、接口类、多单词组成 首字母要大写 XxxYyyZzz
-
变量名、方法名:多单词使用组成,第一单词首字母小写,第二个单词开始每个首字母大写 xxYyyZzz
-
常量名:所有字母都大写。多单词是每个单词用下划线连接XXX_YY_ZZ
3.变量
3.1变量的使用:
-
java定义的变量格式 数据类型 变量名 = 变量值;
-
说明:
- 变量法必须先声明后使用,
- 变量都定义在其作用于内,在作用域内是有效的
- 同一个作用域内不可以声明相同的两个变量
3.2变量的分类
- 按照数据类型分类
-
按照声明的位置分类
成员变量 vs 局部变量
-
long 类型不加L,会默认为int型
float必须加f
整形常量默认类型为int 浮点型默认为double
3.3 基本数据类型的运算
- 自动类型提升
当容量小的数据类型的变量与容量大的数据类型做运算时,结果自动提升为容量大的 数据类型
byte、char、short -->int -->long -->float -->double
特别的 :当byte、char、short三种类型的变量做运算时,结果为int型
- 强制类型转换
-
自动类型提升运算的逆运算
-
需要使用强转符 ()
-
强制类型转换可能损失精度
-
byte、short和char的取值范围交叉,所以需要双向强制转换
double num1 = 2.05; int num = (int) num1; //num = 2 Math.random() * (n - m) + m; //生成[m,n)区间的随机数
最高位为符号位,0为正数,1为负数,负数先除符号位按位取反得到反码,反码加一得到补码,计算机底层存储数据都是用补码
4.运算符
4.1算术运算符
运算符 | 运算 |
---|---|
+ | 正号 |
- | 负号 |
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
% | 取余 |
++a | 先加后用 |
a++ | 先用后加 |
–a | 先减后用 |
a– | 先用后减 |
提示:自加自减运算符谁在前边先用谁
4.2赋值运算符
-
符号:=
当“=”两侧数据类型不一致时,可以使用自动类型转换或使用强制类型转换原则进行处理,支持连续赋值
-
扩展赋值运算符
+= -= /= *= %=
4.3比较运算符
比较运算符 | 运算 | 范例 | 结果 |
---|---|---|---|
== | 相等于 | 4==3 | false |
!= | 不等于 | 4!=3 | true |
< | 小于 | 3<4 | true |
> | 大于 | 4>3 | ture |
<= | 小于等于 | 4<=3 | false |
>= | 大于等于 | 4>=3 | true |
instanceof | 检查是否是类的对象 | “Hello” instanceof String | true |
4.4 逻辑运算符
逻辑运算符 | 运算 | 运算符 | 运算 | 运算符 | 运算 |
---|---|---|---|---|---|
& | 逻辑与 | | | 逻辑或 | ! | 逻辑非 |
&& | 短路与 | || | 短路或 | ^ | 逻辑异或 |
a | b | a&b | a&&b | a|b | a||b | !a | a^b |
---|---|---|---|---|---|---|---|
true | true | true | true | true | true | false | false |
true | false | false | false | true | true | false | true |
false | true | false | false | true | true | true | true |
false | false | false | false | false | false | true | false |
提示:
&和&&的区别
相同点1:&和&&的运算结果相同
相同点2:当符号左边是true时,二者都会执行符号右边的操作
不同点:当符号左边是false时,&继续执行右边的操作,&&不会执行右边的操作
|和||的区别
相同点1:|和||的运算结果相同
相同点2:当符号左边是false时,二者都会执行符号右边的操作
不同点:当符号左边是true时,|继续执行右边的操作,||不会执行右边的操作
4.5位运算符
运算符 | 运算 | 范例 |
---|---|---|
<< | 左移 | 3<<2=12 |
>> | 右移 | 3>>1=1 |
>>> | 无符号右移 | 3>>>1=1 |
& | 与 | 6&3=2 |
| | 或 | 6|3=7 |
^ | 异或 | 6^3=5 |
~ | 取反 | ~6=-7 |
位运算是对整数的二进制进行运算
4.5.1 拓展:权限模块
假设有两张表 用户表 以及 权限表
来源于 Unix 文件控制权限思想
userID | name | password | promission |
---|---|---|---|
1 | 张三 | 1111 | 15 |
2 | 李四 | 2222 | 12 |
3 | 王五 | 333 | 1 |
modId | info | url | value |
---|---|---|---|
1 | 查看 | 1 | |
2 | 添加 | 2 | |
3 | 修改 | 4 | |
4 | 删除 | 8 |
//假如要判断李四是否有修改权限
if(lisi.promission & 4 != 0)
假设李四的权限是: XXXX XXXX
与4进行与运算 &: 0000 0100 //如果李四有修改权限的 4的二进制位就会变成1,
结果 : 0000 0100 //4
//原理:与运算按二进制位运算 如果两个值都是1则为1
//要给王五添加修改权限
if(wangwu.promission | 4 != 0)
假设王五的权限是: XXXX XXXX
与4进行或运算 |: 0000 0100 //如果王五没有修改权限 4的二进制位就会变成1
结果 : XXXX X1XX
//原理:或运算安二进制位 有1则为1
//删除莫个人的修改权限
if(zhangsan.promission ^ -5 != 0)
假设王五的权限是: xxxx xxxx
与4进行异或预算: 0000 0100 //如果张三有修改权限的话 4的二进制位就会变成0
结果 : XXXX X0XX
//原理:异或运算 两个都一样的情况下才会变成0
//有一个int型的数字 XXXXXXXX YYYYYYY ZZZZZZZZ WWWWWWWW
//如果想要后八位 WWWWWWWW
需要将int型 & 1111 1111
xxxx xxxx yyyy yyyy zzzz zzzz wwww wwww
& 0000 0000 0000 0000 0000 0000 1111 1111
//进行与运算 0000 0000 0000 0000 0000 0000 wwww wwww
//想要得到zzzz zzzz的值 先将int型的数字右移八位在与 1111 1111进行与运算
xxxx xxx yyyy yyyy zzzz zzzz wwww wwww >> 8
//溢出之后w位的就不要了 变成 xxxx xxxx yyyy yyyy zzzz zzzz
xxxx xxxx yyyy yyyy zzzz zzzz
& 0000 0000 0000 0000 1111 1111
//进行与运算 0000 0000 0000 0000 zzzz zzzz
拓展:
50 << 1 = 50 * 2;
4.5.2 判断一个数是不是2的次幂
import java.util.Scanner;
public class Test1{
public static void main(String[] args){
System.out.println("input");
Scanner sc = new Scanner(System.in);
int n = Integer.parseInt(sc);
check(n);
}
public static void check(int num){
if( (num & num -1) == 0 ){
//因为num 和 num-1 的二进制数是完全相反的,所以进行与运算的时候,如果是0,则代表是二的次幂
//如果不是0的话,代表这个数与减一的数有一样的,所以就不是而的次幂
System.out.println("shi");
}else{
System.out.println("fou");
}
// 8 0000 1000
// 7 0000 0111
//4 0000 0100
//3 0000 0011
//16 0001 0000
//15 0000 1111
}
}
4.6三元运算符
- 结构: (条件表达式) ? 表达式1 : 表达式2
- 注意
- 条件表达式的结果为boolean类型
- 根据表达式真或假,决定执行表达式1还是表达式2,如果为真执行1,否则执行2
- 三元运算符可以嵌套使用
int m = 10;
int n = 12;
String maxStr = (m > n) ? "m大" : "n 大";
//如果m = n
// String maxStr = (m > n) ? "m大" : ((m == n) ? "m = n" : "n大");
3. 凡是可以用三元运算符的低档都可以用 if -else,反之不行,如果两者都可以使用的话,优先使用 三元运算符,比较简洁高效
5. == 和 equals()的区别
5.1 ==的使用
==:运算符
- 可以使用在基本数据类型变量和引用数据类型变量中
- 如果比较的是基本数据类型变量,比较两个变量保存的数据是否相等(不一定类型要相同);如果比较的是引用数据类型变量,比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体
5.2 equals()方法的使用
- equals()是一个方法,并非运算符
- 只能适用于引用数据类型
- Object类中equals()的定义
public boolean equals(Object obj){
return (this == obj);
}
Object类中定义的equals()和== 的作用是相同的,比较两个对象的地址值是否相同,,即两个引用是否指向同一个对象实体 ;
- 像String、Date、File、包装类等都重写了Object类中的equals()方法,重写以后,比较的不是两个引用地址是否相等。而是比较两个引用的”实体内容“是否相同
- 我们自定义的类使用equals()方法的话,也是比较两个对象的实体内容,那么我们就需要对Object类中的equals()进行重写
public class EqualsTest{
public static void main(String[] args){
int i = 1;
int j = 1;
double d = 1.0;
System.out.println(i == j);//true
System.out.println(i == d);//true
char c = 1;
System.out.println(i == c); //true
char c1 = 'A';
char c2 = 65;
System.out.println( c1 == c2);//true
Customer user1 = new Customer("Tom",21);
Customer user2 = new Customer("Tom",21);
System.out.println( user1 == user2);//false
String str1 = new String("Test");
String str2 = new String("Test");
System.out.println( str1 == str2);//false
System.out.println( user1.equals(user2)); //false
System.out.println( str1.equals(str2)); //true
}
}
//自动创建一个Customer类
//自动生成get 和set方法
//生成一个空参和一个带参构造器
//*************************************
@Override
public boolean equals(Object obj){
if( this == obj){
return true;
}
if( obj instanceof Customer){
Customer cust = (Customer)obj;
return this.age == cust.age && this.name.equals(cust.name);
}
return false;
}
5.3 自动生成重写equals方法
Source --> Generate hashCode() and equals()
6.程序流程控制
6.1 顺序结构
程序从上到下逐行的执行,中间没有任何的判断和跳转
6.2 分支结构
- if - else
if(条件表达式){ 执行表达式 }
if(条件表达式){ 执行表达式1 } else { 条件表达式2 }
if(条件表达式1 ){
执行表达式 1
} else if(条件表达式 2){
执行表达式 2
} else{
执行表达式 3
}
- switch -case
// switch 支持的数据类型有 byte short char int string enum
switch(表达式) {
case 条件1: 执行语句 1;
//break;
case 条件2: 执行语句 2;
//break;
default:执行最终条件;
//break;
}
示例:输入月份和日期,输出是2019年的第几天
import java.util.Scanner;
class SwitchCaseTest{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
System.out.println("请输入2019年的月份");
int month = scan.nextInt();
System.out.println("请输入2019年的日期");
int day = scan.nextInt();
int sumDay = 0;
switch(month){
case 12: sumDay += 30;
//......
case 4: sumDay += 31;
case 3: sumDay += 28;
case 2: sumDay += 31;
case 1: sumDay += day;
}
System.out.println("2019年"+month+"月"+day+"日是当年的第"+sumDay+"天");
}
}
6.3 循环结构
-
for循环
-
do{ … } while
-
while(){ … }
do -while 总是比while 多循环 一次
eg:输出100以内所有的质数
class PrimeNumber{
public static void main(String[] args){
for(int i = 2; i < 100 ; i++){
boolean isFlag = true;
for(int j = 2; j <= Math.sqrt(i);j++){
if(i % j ==0){
isFlag = false;
break; //如果被除尽,跳出
}
}
if( isFlag ){
System.out.print(i+"\t");
}
}
}
}