第二章 Java基础语法
自用学习笔记,用来记录和复习
day05课堂笔记
public class与class的区别
1. 一个Java源文件中可以定义多个class
2. 编译之后,一个class就会对应生成一个class字节码文件
3. 如果一个类是public的,类名必须和源文件名保持一致。
4. public的类可以没有。如果有的话,也只能有一个。
5. 每个类中都可以编写入口main方法。想执行X类的main方法怎么办?java X
6. 这里只是测试一下语法,在实际的开发中,对于一个软件来说,一般入口只有1个。
Java中的标识符
程序员有权力可以自己命名的叫做标识符。
不能用数字开头,使用Unicode编码,可以使用任一国家的文字
遵循驼峰式命名
标识符命名规则:
- 类名,接口名:首字母大写,后面每个首字母大写 StudentService,BankService
- 变量名,方法名:首字母小写,后面每个首字母大写 productPrice,stuName
- 常量名: 全部大写,每个单词之间采用"_"分隔 LOGIN_SECCESS,LOGIN_ERROR
- 包名: 全部小写 com.powernode.javase.chapter02
java语言中是严格区分大小写的。
java语言中的所有关键字都是全部小写。
字面量
程序中的数据就是字面量。字面量是Java中最基本的表达式,无需转换,直接使用。
10 100 123 :整型
1.34 3.14 2.0:浮点型
true false :布尔型
‘a’ ‘国’:字符型 (单引号)
“a” “abc” “国” “中国”:字符串型 (双引号)
Java中的"+"运算符
求和 或 者字符串拼接
两边只要有一边是字符串就会执行字符串的拼接操作
// 如果没有小括号,遵循从左到右
System.out.println(10+20+"30"); // "3030"
变量
变量必须先声明,再赋值,才能访问。
变量作用在域内
一个"{}",就是一个域
变量的分类:
变量可以根据定义/声明的位置来进行分类
- 局部变量:方法体中定义的变量,只在当前方法体中有效
- 成员变量 :类体中定义的变量
- 静态变量 :static int c = 300;
- 实例变量 :int b = 200;
如果成员变量没有手动赋值,系统会赋默认值
day06课堂笔记
进制
二进制 0b
八进制 0
十六进制 0x
原码反码补码
byte(字节) bit(位)
正数的原码补码反码是相同的
- 负数原码:绝对值转换为二进制后,符号位置1
- 负数反码:原码的符号位不变,其他位取反
- 补码:反码加1
数据类型
数据类型的作用:决定给变量分配多大的空间
分为基本数据类型 和 引用数据类型
- 整数
- byte:1字节
- short:2字节
- int:4字节
- long:8字节
- 浮点
- float:4字节
- double:8字节
- 布尔
- boolean:1字节
- 字符
- char:2字节
除此之外都是引用数据类型
整数类型
java中任何一个整数型字面量都会被默认当做int类型处理
// 该程序会报错 不是因为long存不下,而是2147483648被认为是int,在int中存不下
long e = 2147483648;
// 正确如下
long e = 2147483648L;
两个整数类型的数据进行运算之后,结果还是整数类型,除法也是整数
int a = 10;
int b = 3;
System.out.println(a/b); // 3
自动类型转换与强制类型转换
由小容量向大容量进行转换,称为自动类型转换,编译器自动进行
由大容量向小容量进行转换,称为强制类型转换,需要手动进行
// 这是合法的,因为10即使算int类型4字节大于1byte字节,但10没超过byte1字节的范围,
// 所以会自动类型转换
byte a = 10;
// 不合法
byte a = 128;
// 正确应该用强制转换
byte a = (byte)128;
System.out.println(a); // -128
多种数据类型在混合运算的时候,先各自转成容量最大的类型,再进行运算
byte a = 10;
int b = 3;
long c = 100L;
// 报错
int result = a + b + c;
// 正确
long result = a + b + c;
byte和short混合运算时,先各自转换成int再做运算
byte + byte = int
byte + short = int
short + byte = int
short a = 10;
byte b = 10;
// 报错
short result = a + b;
// 应该为int
int result = a + b;
byte a = 10 / 3;在编译期就计算出来,在.class文件中就为byte a=3.
而int result = x / y;在.class文件中为byte result=x/y.
// 编译优化
byte a = 10 / 3;
// 编译阶段只知道是int类型,但不知道具体的结果
byte x = 10;
byte y = 3;
int result = x / y;
浮点型
float:单精度,精确到7位小数
double:双精度,精确到15位小数
double是常用的
浮点型的字面量默认都是double类型
浮点型有两种表示形式
- 十进制: double a = 3.14;
- 科学计数法: double a = 3.14e-2;
浮点数为近似值,所以不能使用"=="与其他数字相等比较
字符类型
字符char类型的字面量必须使用单引号括起来
char类型使用统一的字符编码,使用Unicode编码
可以存储一个汉字
// 不兼容的类型 String无法转换为char
char c = "国"; // 错误 应该使用单引号
char c = 'ab'; // 错误
char c = ''; // 错误 不能为空
char默认值为 \u0000 Unicode编码 表示空字符
char c = '\u0041'; // 正确
char c = \u0041; // 错误
当声明char类型变量的时候,如果值是一个整数型字面量,那么这个字面量会被当成ASCII码来处理
char c = 65;
当整数型字面量没有超出byte short char的范围,可以直接将其赋值给byte short char类型的变量
byte short char混合运算的时候,先各自转换成int在做运算
常见的字符编码
- ASCII: American Standard Code for Information Interchange,美国标准信息交换码 一个字节编码,包括键盘上的所有键
- Latin-1:欧洲标准码,为了表示欧洲语言中的字符设计的
- ANSI:两个ANSI码可以表示一个汉字
- Unicode:国际标准码,占用2个或4个字节,可以表示所有语言的字符,采用十六进制表示,Java中使用的编码方式
- UTF-8:基于Unicode编码的可变长度字符编码,可以表示所有语言的字符,采用UTF-8编码,一个汉字占用三个字节,Web开发中最常用的字符编码方式
- UTF-16:基于Unicode编码的可变长度字符编码,使用2或4个字节表示一个字符
- UTF-32:基于Unicode编码的固定长度字符编码,特点是每个字符占用4个字节
- GB2312:中国国家标准的简体中文字符集,一个汉字占用两个字节,是GBK编码的前身
- GBK:(Guo Biao Ku)使用两个字节表示一个汉字,能够表示中国内地所有的汉字
- GB18030:用于取代GB2312和GBK
- big5:台湾地区的繁体中文字符集,使用两个字节表示一个汉字
基本数据类型转换规则
- 八种基本数据类型中除了boolean类型之外,剩下7个都是可以相互转换的.
- 小容量可以自动转换成大容量,称为自动类型转换,容量从小到大排序:byte < short=char < int < long < float < double
- 大容量不能自动转换成小容量,必须添加强制类型转换符,编译才能通过,但是运行时可能损失精度.
- 当整数型字面量没有超出byte short char的范围时,可以直接将其赋值给byte short char类型的变量
- byte short char混合运算时,先各自转换成int再作运算
- 多种数据类型混合运算时,先各自转换成最大的容量,再做运算
声明编译期就计算出来,而下一行运算时才进行.编译和执行时用的不一套规则
char c1 = 'a' + 1; // 通过
c1 = c1 - 1; // 报错
short s = 10;
s = s - 99; //报错 s-99为int 不能直接赋给short
byte b = 10;
b = b + 1; // 报错 b+1为int 不能直接赋给byte
char c = 'a';
int i = 10;
float f = .3F;
double d = c + i + f; // 通过
byte b1 = 10;
short s1 = 22;
short x = b1 + s1; // 报错
day08课堂笔记
怎么接收用户键盘输入?
// 创建键盘扫描器对象
java.util.Scanner s = new java.util.Scanner(System.in);
// 接收整数
int i = s.nextInt()
// 接收字符串
String str = s.next();
字节码
查看字节码的命令 javap -c Test.class
package myPackage;
public class Test {
public static void main(String[] args) {
int i = 10;
int j = i;
j++;
}
}
在java语言中,任何一个方法执行时,都会专门为这个方法分配所属的内存空间,供这个方法使用.
每个方法都有自己独立的内存空间,这个内存空间中有比较重要的两块:
- 局部变量表(存储局部变量)
- 操作数栈(存储程雪运行过程中参与运算的数据)
bipush 10:将10这个字面量压入操作数栈中
istore_1:将操作数栈顶元素弹出,然后将其存储到局部变量表的1号槽位上.
iload_1:将局部变量表的1号槽位上的元素复制一份,压入操作数栈中.
iinc 2,1:将局部变量表的2号槽位上的元素加1,并将结果存储到2号槽位上.
Compiled from "Test.java"
public class myPackage.Test {
public myPackage.Test();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: bipush 10
2: istore_1
3: iload_1
4: istore_2
5: iinc 2, 1
8: return
}
前缀后缀运算符
实际上找了一个临时变量,将10存起来一份,再做++,然后将10取出覆盖掉11
int i = 10;
i = i++;
System.out.println(i); // 10
int j = 10;
j = ++j;;
System.out.println(j); // 11
逻辑运算符
& 逻辑与
| 逻辑或
^ 逻辑异或: 两结果不一样,结果为true
! 逻辑非
&& 短路与:和逻辑与运算结果完全相同.只不过存在短路现象,即如果左边为false,则右边不执行
|| 短路或:原理同短路与
开发中优先使用短路与和短路或
int x = 99;
int y = 100;
// 逻辑与
System.out.println(x > y & x > ++y)
System.out.println("y = " + y); // 101
// 短路与
System.out.println(x > y && x > ++y)
System.out.println("y = " + y); // 100
按位运算符
任何位运算符,操作的都是补码.
- 左移 <<: 左移一位相当于乘以2.左移运算符不会改变操作数的符号,左移后右补0.无论操作数是正数负数还是0,左移运算符只进行位级移动,不会改变符号.
/* 原码: 10000000 00000000 00000000 01100100 反码: 11111111 11111111 11111111 10011011 补码: 11111111 11111111 11111111 10011100 左移两位: 111111 11111111 11111111 1001110000 原码: 100000 00000000 00000000 0110010000 -400 */ int c = -100; System.out.println(c << 2);
- 右移 >>: 右移一位相当于除以2.右移运算符不会改变操作数的符号.
- 对于正数,符号位不变,右移时左补0
- 对于负数,符号位不变,右移时左补1
- 无符号右移 >>>: 右移时将最高位填充为0.任意一个数字经过无符号右移后,都会为非负数.正数正常右移,负数会变成一个非常大的数(符号位右移了)
- 按位异或:具有自反性 a ^ b ^ b = a;用于加密解密
赋值运算符
// 扩展的赋值运算符,不会改变运算结果类型的
byte a = 10;
a += 10; // 正常 底层实际为 a = (byte)(a + 10);
a = a + 10; // 报错 不兼容的类型
分支语句Switch
switch(表达式)
表达式的值必须为:int,枚举,字符串.不支持boolean等
switch语句使用于判断固定值,if语句适用于判断范围或区间时使用,switch能做的if肯定能做,if能完成的switch不一定能完成
JDK7之前,switch只支持int类型,枚举类型.JDK之后增加了对字符串的支持.
case语句中的值必须为字面量,不能是变量.值必须与表达式的值类型一致,否则编译不通过.
Java12支持 case 1,2,3 -> 语句
方法
方法(Method) 是一段可以被重复利用的代码段,即C语言中的 函数.代码复用
- 语法格式:
[修饰符列表] 返回值类型 方法名(形式参数列表){ 方法体; }
- 修饰符列表:public static
- 返回值类型:可以是任意数据类型,包括基本数据类型,引用数据类型
- 返回值一定要和返回值类型一致,或者能够自动类型转换,或者强制类型转换
- 方法名:首字母小写,后面每个单词首字母大写
- 方法的调用
- 类名.方法名(实参列表);
- 调用者和被调用者在一个类里,可以省略类名.
方法调用的瞬间,会在JVM的栈内存中分配活动场所,此时发生压栈操作
方法一旦结束,给该方法分配的内存空间就会释放,此时发生弹栈动作
方法重载(overload)
在Java语言中允许在一个类中定义多个方法,这些方法的名字可以一致.
addInt,addDouble,addString类似,可以用同一个名字,但形参列表不同
什么情况下我们考虑使用方法重载机制?
当功能相似的时候,建议将方法名定义为一致的,
这样代码美观,又方便编程。
注意:如果功能不相似,坚决要让方法名不一致。
代码满足什么条件的时候构成了方法重载?
条件1:在同一个类当中
条件2:方法名相同
条件3:形式参数列表不同(类型、个数、顺序)名称不行
注意:方法重载和返回值类型无关,和修饰符列表无关。
Package包机制
package只能出现在代码的第一行
带包编译: javac -d 生成路径
有了package之后,完整的类名是带包名的,运行时一定要添加包名
所有的包名都是小写
命名规范:公司域名倒序+项目名+模块名+功能名
例如: com.powernode.oa.empmgt.service
import
import只能出现在package和class定义之间
什么时候必须使用import语句?
A类中使用B类,当A和B类不在同一个包下,并且B类也不属于java.lang包,必须使用import引入
import支持模糊导入:如import java.util.*;
静态导入,将System类中所有静态变量和静态方法全部导入(可读性差,最好别用)
import static java.lang.System.\*;
IDEA快捷键
alt+insert(新建任何东西)
ESC 退出任何窗口
ctrl+shift+F12 编写源码的窗口最大化
psvm生成main方法
sout生成println
“字符串”.sout 生成println
ctrl+shift+F10 运行程序
alt+1 打开project窗口
shift+shift 查看源码
alt+左右 切换选项卡
.var 自动色生成变量
ctrl+y 删除一行
ctrl+d 复制一行
回车会自动到下一个合适的位置
ctrl+F12 在一个类中找方法
ctrl+shift+/ 多行注释
查看源码:按ctrl不松手,鼠标移动到对应的类名下方,出现下划线,点击过去可以查看类源码
多行编辑:按alt不松手,鼠标拖动多行,完成多行编辑
快速生成创建对象语句:类名.new.var