# Java语言基础
# JDK下载
Adoptium的OpenJDK:https://adoptium.net/zh-CN/
Oracle官网下载地址:https://www.oracle.com/java/technologies/downloads/
# Java语言及类库的演进
版本 | 年份 | 新语言特性 | 类与接口的数量 |
---|---|---|---|
1.0 | 1996 | 语言本身 | 211 |
1.1 | 1997 | 内部类 | 477 |
1.2 | 1998 | strictfp修饰符 | 1524 |
1.3 | 2000 | 无 | 1840 |
1.4 | 2002 | 断言 | 2723 |
5.0 | 2004 | 泛型类、"for each"循环、可变参数、自动装箱、元数据、枚举、静态导入 | 3279 |
6 | 2006 | 无 | 3793 |
7 | 2011 | 基于字符串的Switch语句、菱形运算符、二进制字面量、异常处理增强 | 4024 |
8 | 2014 | Lamda表达式、包含默认方法的接口、流和日期/时间库 | 4240 |
9 | 2017 | 模块、其他的语言和类库增强 | 6005 |
11 | 2018 | 局部变量类型推导(var)、Http客户端,移除Java FX、JNLP、Java EE重叠模块和CORBA | 4410 |
17 | 2021 | Switch表达式、文本块、instanceof模式匹配、记录、密封类 | 4859 |
21 | 2023 | 虚拟线程(Virtual threads),模式匹配(pattern matching) | 4882 |
# 基本数据类型
Java中数据类型分为基本数据类型和引用数据类型。这些基本数据类型的数据变量在声明之后就会立刻在栈上被分配内存空间。
基本类型 | 大小 | 默认值 | 最小值 | 最大值 | 包装类型 |
---|---|---|---|---|---|
boolean | ---- | ---- | ---- | ---- | Boolean |
char | 16bits | \u0000 | \u0000 | \uffff | Character |
byte | 8bits | 0 | -128(-2^7) | +127(2^7-1) | Byte |
short | 16bits | 0 | -32768(-2^15) | +32767(2^15-1) | Short |
int | 32bits | 0 | -2,147,483,648(-2^31) | 2,147,483,647(2^31-1) | Integer |
long | 64bits | 0L | -9,223,372,036,854,775,808(-2^63) | 9,223,372,036,854,775,807(2^63-1) | Long |
float | 32bits | 0.0f | IEEE 754 | IEEE 754 | Float |
double | 64bits | 0.0d | IEEE 754 | IEEE 754 | Double |
char类型的字面值要用单引号括起来,长整型数值有一个后缀L或l,十六进制数值有一个前缀0x或0X,八进制有一个前缀0,0b或0B标识二进制,float类型的数值有一个后缀F或f,没有F或f的数值默认为double,也可在double数值后面添加后缀D或d。所有浮点数计算都遵循IEEE754规范。如果需要精确的数值计算,不允许有舍入误差,则应该使用BigDecimal类。整型值和布尔值之间不能进行相互转换。
类(默认值null)、接口(默认值null)、数组(默认值null)。
# Java注释有三种
单行注释,//注释本行
/* */两个注释界定符将一段很长的注释括起来,可换行,但不能多个/* */嵌套
/** */可以用来自动生成文档
# Java变量与命名
Java是一种强类型语言,声明一个变量时,先指定变量的类型。作为变量名的标识符由字母、数字、货币符号以及"标点连接符"组成。第一个字符不能是数字。'+'和'©'之类的符号不能出现在变量名中,空格也不行。字母区分大小写。标识符的长度基本上没有限制。不能使用Java关键字作为变量名。在Java9中,单下划线_是一个保留字,将来的版本可能使用_作为通配符。
Java区分大小写。类名必须以字母开头,后面可以跟字母和数字的任意组合,长度基本上没有限制。标准命名约定为,类名是以大写字母开头的名词,如果名字由多个单词组成,每个单词的第一个字母都应该大写,也就是驼峰命名法。源代码的文件名必须与公共类的类名相同,并用.java作为扩展名。
# 常量
可以用关键字final指示常量,关键字final表示这个变量只能被赋予一次,一旦赋值,就不能再更改了。习惯上,常量名使用全大写。可以使用关键字static final设置一个类常量。
# 数值类型之间的转换
# 位运算符
& (and) | (or) ^ (xor) ~ (not) >> (左移,会用符号位填充高位) << (右移) >>>(左移,运算符会用0填充高位)
不存在<<<运算符
&&的优先级比||的优先级高
# 字符串
Java字符串就是Unicode字符序列,每个用双引号括起来的字符串就是String类的一个实例。当将一个字符串与一个非字符串的值进行拼接时,后者会转换成字符串。如果需要把多个字符串放在一起,用一个界定符分隔,可以使用静态join方法。字符串不可变,编译器可以让字符串共享。原始字符串在堆中分配。可以使用equals方法检测两个字符串是否相等,不要使用==运算符检测两个字符串是否相等,这个运算符只能够确定两个字符串是否存放在同一个位置上。如果虚拟机总是共享相等的字符串,则可以使用==运算符检测字符串是否相等。但实际上只有字符串字面量会共享,而+或substring等操作得到的字符串并不共享。空串""是长度为0的字符串。空串是一个Java对象,有自己的串长度(0)和内容(空)。不过,String变量还可以存 放一个特殊的值,名为null ,表示目前没有任何对象与该变量关联。如果采用字符串拼接的方式来构建字符串,效率会比较低。每次拼接字符串时,都会构建一个新的 String对象,既耗时 ,又浪费空间 。使用StringBuilder类就可以避免这个问题。StringBuffer)类的效率不如StringBuilder类,不过它允许采用多线程的方式添加或删除字符。
Java15新增的文本块(textblock)特性,可以很容易地提供跨多行的字符串字面量。 文本块以"""开头 (这是开始"""),后面是一个换行符,并以另一个"""结尾(这是结束""")。
# switch语句
case标签可以是byte,short,int,char。JDK5以后可以是枚举,JDK7以后可以是String。多个字符串,用逗号分隔。不能在一个swit ch语句中混合使用冒号和箭头。在Java中,switch表达式直通式是指当switch块中的一个case匹配并执行后,如果没有遇到break语句,那么程序会继续执行下一个case中的语句,而不是立即退出switch结构。这种行为称为直通式。
//旧语法
int number = 1;
switch (number){
case 1:
System.out.println("1");
break;
case 2:
System.out.println("2");
break;
case 3:
System.out.println("3");
break;
default:
System.out.println("");
break;
}
//新语法糖,break可以省略,也没有直通式行为
int number = 2;
switch (number){
case 1 -> {
System.out.println("1");
}
case 2 -> {
System.out.println("2");
}
case 3 -> {
System.out.println("3");
}
default -> {
System.out.println("");
}
}
//若语句体中只有一条语句,大括号也可省略
int number = 1;
switch (number){
case 1 -> System.out.println("1");
case 2 -> System.out.println("2");
case 3 -> System.out.println("3");
default -> System.out.println("");
}
//旧语法,有直通式行为
int number 4;
switch (number){
case 1:
case 2:
case 3:
case 4:
case 5:
System.out.println("weekday");
break;
case 6:
case 7:
System.out.println("weekend");
break;
default:
System.out.println("error");
break;
}
//新语法糖,有直通式行为
int number = 7;
switch (number){
case 1,2,3,4,5 -> System.out.println("weekday");
case 6,7 -> System.out.println("weekend");
default -> System.out.println("error");
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
注意switch表达式中的yield关键字。与break类似,yield会终止执行。但与break不同的是,yield还会生成一个值,这就是表达式的值。要在switch 表达式的一个分支中使用语句而不想有直通行为,就必须使用大括号和 yield。不能在switch表达式中使用return、break或continue语句。
# 大数
java.nath包中两个很有用 的类:BigIntegey和BigDecimal,这两个类可以处理包含任意长度数字序列的数值。BIgInteger 类实现任意精度的整数运算,BigDecinaL实现任意權度的浮点数运算。不能使用人们熟悉的算术运算符(如:+和*)来组合大数,而需要使用大数类中的add和multiply方法。
# 类之间的关系
类关系 | 描述 | 权力强侧 | 举例 |
---|---|---|---|
继承 | 父子类之间的关系:is-a | 父类 | 小狗继承于动物 |
实现 | 接口和实现类之间的关系:can-do | 接口 | 小狗实现了狗叫接口 |
组合 | 比聚合更强的关系:contains-a | 整体 | 头是身体的一部分 |
聚合 | 暂时组装的关系:has-a | 组装方 | 小狗和绳子是暂时的聚合关系 |
依赖 | 一个类用到另一个:depends-a | 被依赖方 | 人养小狗,人依赖于小狗 |
关联 | 平等的使用关系:links-a | 平等 | 人使用卡消费,卡可以提取人的信息 |
# 用var声明局部变量
在Java10中,如果可以从变量的初始值推导出它们的类型,那么可以用var 关键字声明 局部变量,而无须指定类型。var关键字只能用于方法中的局部变量。
Java允许重载任何方法,而不只是构造器方法。要完整地描述一个方法,需要指定方法名以及参数类型,这叫作方法的签名。返回类型不是方法签名的一部分。也就是说,不能有两个名字相同、参数类型也 相同却有不同返回类型的方法。返回类型不是方法签名的一部分。也就是说,不能有两个名字相同、参数类型也 相同却有不同返回类型的方法。
如果你写的类没有构造器,就会为你提供 一个无参数构造器。这个构造器将所有的实例 字段设置为相应的默认值。如果类中提供了至少一个构造器,但是没有提供无参数构造器,那么构造对象时就必须 提供参数,否则就是不合法的。尚类没有任何其他构造器的时候,你才会得到一个默认的无参数构造器。this指示隐式参数。
# 记录
JDK14引入了一个预览特性:"记录"。最终版本在JDK16 中发布。记录(record)是一种特殊形式的类,其状态不可变,而且公共可读。在Java语言规范中,一个记录的实例字段称为组件(component)。记录的实例字段自动为final字段。对于完全由一组变量表示的不可变数据,要使用记录而不是类。如果教据是可变的,或者数据表示可能随时间改变,则使用类。记录更易读、更高效,而且在形发程序中更安全
友情链接:
Adoptium的OpenJDK:https://adoptium.net/zh-CN/
Oracle官网下载地址:https://www.oracle.com/java/technologies/downloads/
Core Java第十三版第一卷(英文版)下载地址:https://library.lol/main/1863767A9A332F5A2317AAFF24007AFD
Core Java第十三版第二卷(英文版)下载地址:https://library.lol/main/91F8F511C4441F0B2D55E0C04025F355 Java17API文档:https://docs.oracle.com/en/java/javase/17/docs/api/