简介

详细api方法可以查看:官方API文档

语法与 C、C++接近,且丢弃了 C++中很少使用的特性。此外,java 还不使用指针,而是引用,并提供了自动分配和回收内存空间,使得我们不用为内存管理而担忧。

运行环境,最好保证操作系统内存 1G 以上

基本数据类型

变量就是申请内存来存储值。

Java 的两大数据类型:

  • 内置数据类型
  • 引用数据类型

内置数据类型

类型 字节大小 大小(位) 最小值 最大值 默认值 包装类 备注说明
byte 1 8 -2^7 2^7 - 1 0 Byte 有符号整数
short 2 16 -2^15 2^15 - 1 0 Short 有符号整数
int 4 32 -2^31 2^31 - 1 0 Integer 有符号整数,最常用
long 8 64 -2^63 2^63 - 1 0L Long 需加 L 后缀(如 1000L)
float 4 32 ≈1.4E-45 ≈3.4E38 0.0f Float 单精度浮点,需加 f 后缀
double 8 64 ≈4.9E-324 ≈1.8E308 0.0d Double 双精度浮点(默认浮点类型)
char 2 16 0 2^16 - 1 ‘\u0000’ Character 无符号 Unicode 字符
boolean 1/8 1 false true false Boolean 大小取决于 JVM 实现

浮点数设计与整型不同,遵循IEEE 754 浮点数标准 ​​,不能用 2 的幂函数表示

引用数据类型

所有引用类型的默认值都是 null,如 String、array。

常量

在程序运行时,是不能被修改的。使用final进行修饰。

自动类型转换

在混合运算中,不同的类型是先转为同一类型,再进行计算,转换从低级到高级。

1
2
低  ------------------------------------>  高
byte,short,char—> int —> long—> float —> double

强制类型转换

如下:

1
2
3
int i1 = 123;
byte b = (byte)i1;//强制类型转换为byte
System.out.println("int强制类型转换为byte后的值等于"+b);

需要注意的是,强转是由高–>低,会出现溢出或者精度损失的情况。如上述代码,其中 i1,因为 byte 类型是八位,最大值是 127,当 i1=128 时,就会导致溢出。

隐含强制类型转换

只需要记住两点:

  • 整数的默认类型是 int。
  • 小数默认是 double 类型浮点型,在定义 float 类型时必须在数字后面跟上 F 或者 f。

怎么理解呢?就比如:float aa = 12.9;,这个赋值后面没有加 F/f,其实它完整的写法是:float aa = (float) 12.9;,中间有一个隐形的转换过程,因为小数 12.9 默认是 double 类型的。

变量类型

变量类型 声明位置 作用域 生命周期
局部变量 方法/构造块/代码块内部 仅在声明它的代码块内有效 从声明开始到代码块结束
实例变量 类内部(方法外部) 类实例内部有效 对象创建 → 对象被垃圾回收
静态变量 类内部 + static修饰 整个类范围(所有实例共享) 类加载时存在 → 程序结束
参数变量 方法/构造函数参数列表 整个方法/构造函数内部有效 方法调用开始 → 方法执行结束

参数变量

方法参数来那个量的值传递方式有两种:值传递引用传递

  • 值传递:基本类型都是采用值传递,它传递的是实际参数变量值的副本,不会对原本的参数变量造成影响。
  • 引用传递:对象类型采用引用传递方式传递值,它传递的是实际参数变量的引用(内存地址),当变量参数被赋予新的值时,会修改原始值。

访问修饰符

修饰符分为访问修饰符非访问修饰符

访问修饰符

访问修饰符 同类 同包子类 同包非子类 不同包子类 不同包非子类 说明
public 全局可见
protected 子类可见(即使跨包)
default 包内可见(默认修饰符)
private 仅类内可见

非访问修饰符

非访问修饰符 适用位置 用途说明
static 变量/方法/代码块 声明类级别成员(无需实例化即可访问)
final 类/方法/变量 禁止继承/重写/修改
abstract 类/方法 定义抽象类或抽象方法(要求子类实现)
synchronized 方法/代码块 线程同步(一次只允许一个线程访问)
volatile 变量 线程间可见性(变量直接读写主内存)
transient 变量 序列化时排除字段
native 方法 声明本地方法(用非Java语言实现)

运算符

算术运算符

运算符 名称 示例 说明
+ 加法 a + b 也用于字符串连接
- 减法 a - b
* 乘法 a * b
/ 除法 a / b 整数除法会截断小数
% 取模 10 % 31 计算余数
++ 自增 a++++a 前缀/后缀影响计算顺序
-- 自减 b----b 前缀/后缀影响计算顺序

关系运算符

运算符 名称 示例 说明
== 等于 a == b 比较基本类型值或对象引用
!= 不等于 a != b
> 大于 a > b
< 小于 a < b
>= 大于等于 a >= b
<= 小于等于 a <= b

逻辑运算符

运算符 名称 示例 说明
&& 逻辑与 a > 0 && b < 10 短路运算(前false则跳过计算)
|| 逻辑或 a < 0 || b > 5 短路运算(前true则跳过计算)
! 逻辑非 !valid 取反操作

位运算符

运算符 名称 示例 说明
& 按位与 mask & options 二进制位运算
| 按位或 mask | flags
^ 按位异或 a ^ b 相同为0,不同为1
~ 按位取反 ~value 0变1,1变0
<< 左移 num << 2 相当于*4
>> 带符号右移 num >> 1 最高位补符号位
>>> 无符号右移 num >>> 3 最高位补0

其他运算符

类别 运算符 名称/作用 示例 说明
赋值运算符 = 赋值 int x = 5;
+= -= 复合赋值 a += 3; 等价于 a = a + 3
三元运算符 ? : 条件运算符 max = (a>b) ? a : b; 简化if-else
类型检查 instanceof 实例检查 obj instanceof String 检查对象类型
成员访问 . 点运算符 obj.method() 访问对象成员
优先级控制 () 括号 (a+b)*c 改变运算顺序

数组

1.声明

1
2
3
dataType[] arrayRefVar;   // 首选的方法

dataType arrayRefVar[]; // 效果相同,但不是首选方法

2.创建

1
arrayRefVar = new dataType[arraySize];

1&2合起来就是:dataType[] arrayRefVar = new dataType[arraySize];
此外,还可以像这样:dataType[] arrayRefVar = {value0, value1, ..., valuek};

可以使用 java.util.Arrays 工具类,方便操作数组,其中最常用的就是,Arrays.sort(array),排序数组。

正则表达式

Java 提供了 java.util.regex 包,它包含了 Pattern 和 Matcher 类,用于处理正则表达式的匹配操作。

1
2
3
4
5
6
String line = "This order was placed for QT3000! OK?";
String pattern = "(\\D*)(\\d+)(.*)";
// 创建 Pattern 对象
Pattern r = Pattern.compile(pattern);
// 现在创建 matcher 对象
Matcher m = r.matcher(line);

正则表达式语法可以查看:菜鸟教程/正则表达式/正则表达式语法

方法

方法重载 (Overloading)

核心概念
同一个类中,允许存在多个同名方法,但要求它们的参数列表不同(类型、数量或顺序不同)。

规则

  1. 方法名必须相同
  2. 参数列表必须不同(以下至少满足一项):
    • 参数类型不同
    • 参数数量不同
    • 参数顺序不同
  3. 与返回值类型无关(返回值可相同也可不同)

可变参数 (Varargs)

核心概念
允许方法接受任意数量的同类型参数(本质是数组的语法糖)。

语法
在参数类型后加 ...
void methodName(Type... varName)

规则

  1. 一个方法只能有一个可变参数
  2. 必须是方法的最后一个参数
  3. 可以接受 0 到多个参数

构造方法

用来创建类的实例对象的方法。
特点 :

  1. 与类名相同;
  2. 没有返回类型;
  3. 默认构造方法,在没有定义任何构造方法的时候,java会自动提供一个无参构造方法;
  4. this关键字使用,在调用其他构造方法时,必须放在构造方法的第一行;
  5. 不能被继承,但是可以被调用,子类使用 super();

异常处理

主要分为三种异常:

  1. 检查性异常,可以使用try-catch或者throws来处理。
1
2
3
4
5
6
7
8
9
10
11
try (resource declaration) {
// 使用的资源
} catch (ExceptionType e1) {
// 异常块
}finally{

}
// ===========or========
public void readFile() throws IOException {
// 可能会抛出IOException的代码
}
  1. 运行时异常,最常见的就是 NullPointerException

  2. 错误:不是异常,容易忽略的地方,比如栈溢出。

throw 用于手动抛异常,如:

1
2
3
4
5
 public void checkNumber(int num) {
if (num < 0) {
throw new IllegalArgumentException("Number must be positive");
}
}

常用类

Number

Number 是除开 boolean 和 Character 之外的所有基本数字类型的包装类的抽象父类,提供各种数值类型的转换。

主要子类:

1
2
Integer num1 = Integer.valueOf("100");
Double num2 = Double.parseDouble("3.14");
  1. 基本类型转换
1
2
3
4
5
6
Number num = 1234.56; // 实际是Double类型

System.out.println(num.intValue()); // 1234 (截断小数)
System.out.println(num.longValue()); // 1234
System.out.println(num.floatValue()); // 1234.56
System.out.println(num.doubleValue()); // 1234.56
  1. 数值比较
1
2
3
4
5
Integer x = 10;
Double y = 10.0;

// 正确比较方式:转换为同一类型后比较
System.out.println(x.doubleValue() == y.doubleValue()); // true
  1. 处理大数
1
2
3
4
5
6
BigInteger bigInt = new BigInteger("12345678901234567890");
BigDecimal bigDec = new BigDecimal("1234567890.1234567890");

// 大数运算
BigInteger sum = bigInt.add(new BigInteger("1"));
BigDecimal product = bigDec.multiply(new BigDecimal("2"));
  1. 数值格式化
1
2
3
4
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(2);

System.out.println(nf.format(1234.5678)); // "1,234.57"
  1. 自动装箱和拆箱
1
2
3
4
5
// 自动装箱,装箱后的对象是Number的子类
Integer autoBoxed = 42; // 编译器转换为 Integer.valueOf(42)

// 自动拆箱,调用Number.xxxValue()实现的
int autoUnboxed = autoBoxed; // 编译器转换为 autoBoxed.intValue()

Math

常用的数学函数、公式和特征值。

1
2
3
4
// 生成[0.0, 1.0)之间的随机数
double random = Math.random();
// 生成[1, 100]的随机整数
int randomInt = (int)(Math.random() * 100) + 1;

Character

Character 类用于对单个字符进行操作。

Character 类在对象中包装一个基本类型 char 的值,用于处理需要对象,而不是内置数据的情况。
示例:

1
2
3
4
5
6
7
8
9
10
char ch = 'a';

// Unicode 字符表示形式
char uniChar = '\u039A';

// 字符数组
char[] charArray ={ 'a', 'b', 'c', 'd', 'e' };

// 对象
Character ch = new Character('a');

String

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
String str = "hello world";
String str2=new String("hello world");

//连接字符串
str.concat(str2);

//创建格式化字符串
System.out.printf("浮点型变量的值为 " +
"%f, 整型变量的值为 " +
" %d, 字符串变量的值为 " +
" %s", floatVar, intVar, stringVar);

String fs;
fs = String.format("浮点型变量的值为 " +
"%f, 整型变量的值为 " +
" %d, 字符串变量的值为 " +
" %s", floatVar, intVar, stringVar);

StringBuffer

对字符串修改时候会用到,与 String 不同的是,这两个被多次修改也不会产生新的对象。
StringBuilder 线程不安全速度快,多线程使用 StringBuffer

特性 String StringBuffer StringBuilder
可变性 ✔️ ✔️
线程安全 ✔️
性能

Scanner

获取用户的输入:

1
2
3
4
5
6
7
8
9
10
11
Scanner s = new Scanner(System.in);
// 从键盘接收数据

// next方式接收字符串
System.out.println("next方式接收:");
// 判断是否还有输入
if (scan.hasNext()) {
String str1 = scan.next();
System.out.println("输入的数据为:" + str1);
}
scan.close();

其他不过多记录,用得少

Stream、File、IO

字节流

字节流用于处理二进制数据,例如文件、图像、视频等。

类名 类型 描述
InputStream 抽象类(输入流) 所有字节输入流的超类,处理字节的输入操作。
OutputStream 抽象类(输出流) 所有字节输出流的超类,处理字节的输出操作。
FileInputStream 输入流 从文件中读取字节数据。
FileOutputStream 输出流 将字节数据写入文件。
BufferedInputStream 输入流 为字节输入流提供缓冲功能,提高读取效率。
BufferedOutputStream 输出流 为字节输出流提供缓冲功能,提高写入效率。
ByteArrayInputStream 输入流 将内存中的字节数组作为输入源。
ByteArrayOutputStream 输出流 将数据写入到内存中的字节数组。
DataInputStream 输入流 允许从输入流中读取 Java 原生数据类型(如 int, float, boolean)。
DataOutputStream 输出流 允许向输出流中写入 Java 原生数据类型。
ObjectInputStream 输入流 从输入流中读取序列化对象。
ObjectOutputStream 输出流 将对象序列化并写入输出流中。
PipedInputStream 输入流 用于在管道中读取字节数据,通常与 PipedOutputStream 配合使用。
PipedOutputStream 输出流 用于在管道中写入字节数据,通常与 PipedInputStream 配合使用。
FilterInputStream 输入流 字节输入流的包装类,用于对其他输入流进行过滤处理。
FilterOutputStream 输出流 字节输出流的包装类,用于对其他输出流进行过滤处理。
SequenceInputStream 输入流 将多个输入流串联为一个输入流进行处理。

字符流

字符流用于处理文本数据,例如读取和写入字符串或文件。

类名 类型 描述
Reader 抽象类 (输入流) 所有字符输入流的超类,处理字符的输入操作。
Writer 抽象类 (输出流) 所有字符输出流的超类,处理字符的输出操作。
FileReader 输入流 从文件中读取字符数据。父类是 InputStreamReader
FileWriter 输出流 将字符数据写入文件。父类是 OutputStreamWriter
BufferedReader 输入流 为字符输入流提供缓冲功能,支持按行读取,提高读取效率。
BufferedWriter 输出流 为字符输出流提供缓冲功能,支持按行写入,提高写入效率。
CharArrayReader 输入流 将字符数组作为输入源。
CharArrayWriter 输出流 将数据写入到字符数组。
StringReader 输入流 将字符串作为输入源。
StringWriter 输出流 将数据写入到字符串缓冲区。
PrintWriter 输出流 便捷的字符输出流,支持自动刷新和格式化输出。
PipedReader 输入流 用于在管道中读取字符数据,通常与PipedWriter配合使用。
PipedWriter 输出流 用于在管道中写入字符数据,通常与PipedReader配合使用。
LineNumberReader 输入流 带行号的缓冲字符输入流,允许跟踪读取的行号。
PushbackReader 输入流 允许在读取字符后将字符推回流中,以便再次读取。

辅助类

辅助类提供对文件、目录以及随机文件访问的支持。

姓名 类型 描述
File 文件和目录操作 用于表示文件或目录,并提供文件操作,如创建、删除、重命名等。
RandomAccessFile 随机访问文件 支持文件的随机访问,可以从文件的任意位置读写数据。
Console 控制台输入输出 提供对系统控制台的输入和输出支持。

基本例子

FileInputStream

输入流对象来读取文件

1
2
3
4
InputStream f = new FileInputStream("C:/java/hello");
//或者
File f = new File("C:/java/hello");
InputStream in = new FileInputStream(f);
FileOutputStream

该类用来创建一个文件并向文件中写数据。

1
2
3
4
OutputStream f = new FileOutputStream("C:/java/hello")
//或者
File f = new File("C:/java/hello");
OutputStream fOut = new FileOutputStream(f);

编码例子

涉及到编码转换的写入和读取。

1
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
File f = new File("a.txt");
// 构建FileOutputStream对象,文件不存在会自动新建
FileOutputStream fop = new FileOutputStream(f);
// 构建OutputStreamWriter对象,参数可以指定编码,默认为操作系统默认编码,windows上是gbk
OutputStreamWriter writer = new OutputStreamWriter(fop, "UTF-8");
// 写入到缓冲区
writer.append("中文输入");
// 换行
writer.append("\r\n");
// 刷新缓存冲,写入到文件,如果下面已经没有写入的内容了,直接close也会写入
writer.append("English");
// 关闭写入流,同时会把缓冲区内容写入文件,所以上面的注释掉
writer.close();
// 关闭输出流,释放系统资源
fop.close();

// 构建FileInputStream对象
FileInputStream fip = new FileInputStream(f);
// 构建InputStreamReader对象,编码与写入相同
InputStreamReader reader = new InputStreamReader(fip, "UTF-8");
StringBuffer sb = new StringBuffer();
while (reader.ready()) {
// 转成char加到StringBuffer对象中
sb.append((char) reader.read());
}
System.out.println(sb.toString());
// 关闭读取流
reader.close();
// 关闭输入流,释放系统资源
fip.close();

日期时间相关类

Date

(已过时,建议使用 java.time 包)

基本使用
1
2
Date now = new Date(); // 当前时间
long time = now.getTime(); // 时间戳

SimpleDateFormat

日期格式化类
(可以使用 java.time 中的 DateTimeFormatter 替代)

使用示例
1
2
3
4
5
6
7
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

// 日期转字符串
String str = sdf.format(new Date());

// 字符串转日期
Date date = sdf.parse("2023-01-01 12:00:00");
注意事项
  • 非线程安全,多线程环境需配合 ThreadLocal 使用
  • 格式符号:yyyy-年,MM-月,dd-日,HH-小时(24h 制)

Calendar

日期操作类

常用方法
1
2
3
4
5
6
7
8
9
10
Calendar cal = Calendar.getInstance();

// 获取字段
int year = cal.get(Calendar.YEAR);

// 设置时间
cal.set(2023, Calendar.JANUARY, 1);

// 日期计算
cal.add(Calendar.DAY_OF_MONTH, 5); // 加5天
注意事项
  • 月份从 0 开始(0=January)
  • 推荐使用 Calendar.getInstance() 获取实例

java.time

参考:https://javaguidepro.com/blog/datetime-java/

基本使用
1
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
// 获取当前日期
LocalDate currentDate = LocalDate.now();
// 创建指定日期
LocalDate specificDate = LocalDate.of(2024, 1, 1);
// 获取当前时间
LocalTime currentTime = LocalTime.now();
// 创建指定时间
LocalTime specificTime = LocalTime.of(12, 30, 0);
// 获取当前日期时间
LocalDateTime currentDateTime = LocalDateTime.now();
// 创建指定日期时间
LocalDateTime specificDateTime = LocalDateTime.of(2024, 1, 1, 12, 30, 0);
// 获取当前带时区的日期时间
ZonedDateTime currentZonedDateTime = ZonedDateTime.now();

// 指定时区创建日期时间
ZoneId zoneId = ZoneId.of("Asia/Shanghai");
ZonedDateTime specificZonedDateTime = ZonedDateTime.of(2024, 1, 1, 12, 30, 0, 0, zoneId);

// 定义格式化模式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 格式化日期时间
LocalDateTime dateTime = LocalDateTime.now();
String formattedDateTime = dateTime.format(formatter);

// 比较日期
LocalDate startDate = LocalDate.of(2024, 1, 1);
LocalDate endDate = LocalDate.of(2024, 12, 31);
boolean isBefore = startDate.isBefore(endDate);

// 计算日期差值
Period period = Period.between(startDate, endDate);
System.out.println("两个日期之间的差值: " + period.getYears() + " 年 " + period.getMonths() + " 月 " + period.getDays() + " 天");
String dateStr = "2024-01-01";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

// 解析日期字符串
LocalDate parsedDate = LocalDate.parse(dateStr, formatter);
System.out.println("解析后的日期: " + parsedDate);

// 指定一个日期(例如:2023-10-01)
LocalDate specifiedDate = LocalDate.of(2023, 10, 1);
// 获取该日期后5天的日期
LocalDate resultDate = specifiedDate.plusDays(5);

参考