Java基础笔记
一、数据类型与变量
1. 8种基本数据类型(4大类)
| 类型 | 关键字 | 字节 | 默认值 | 包装类 |
|---|---|---|---|---|
| 整型 | byte | 1 | 0 | Byte |
| short | 2 | 0 | Short | |
| int | 4 | 0 | Integer | |
| long | 8 | 0L | Long | |
| 浮点型 | float | 4 | 0.0f | Float |
| double | 8 | 0.0d | Double | |
| 字符型 | char | 2 | '\u0000' (空) | Character |
| 布尔型 | boolean | 1位 | false | Boolean |
long后缀L,float后缀f,char字面量用单引号。- 所有数值类型默认值都是
0(或0.0)。
2. 变量类型
- 局部变量:声明在方法/构造/代码块中,必须显式初始化,作用域仅限于当前块,存储在栈内存。
- 实例变量:声明在类中但方法外,属于对象,有默认值,存储在堆内存,随对象销毁。
- 类变量(静态变量):使用
static声明,属于类,所有实例共享,类加载时初始化,可通过类名直接访问,存储在方法区(元空间)。
3. 类型转换
- 自动类型转换:小范围→大范围,编译器自动完成,不会丢失精度(
long→float可能丢失精度)。 - 强制类型转换:大范围→小范围,需显式使用
(类型),可能丢失精度或溢出。 - 包装类转换:自动装箱/拆箱。例如
Integer b = 10;(装箱),int d = b;(拆箱)。
注意:-128~127范围内的Integer会被缓存,复用同一对象。 - 字符串转换:基本类型→字符串用
String.valueOf(),字符串→基本类型用parseXxx()。
二、运算符与表达式
- 优先级:
* / %>+ ->== !=>&&>||。建议使用括号明确顺序。 - 复合赋值:
+=、-=等可简化代码。 - 浮点数比较:使用误差范围(如
Math.abs(a - b) < 1e-6),避免直接==。 字符串比较:
==比较引用地址。equals()比较内容。compareTo()返回大小关系(正/零/负)。
- 自增/自减:避免在复杂表达式中使用,如
i++ + ++i。
三、输入输出(Scanner)
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); // 读取整数
double d = sc.nextDouble(); // 读取浮点数
String s1 = sc.next(); // 读到空格或换行
String s2 = sc.nextLine(); // 读取整行
boolean b = sc.nextBoolean();
// 检查方法
if (sc.hasNextInt()) { ... }- 缓存问题:
nextInt()后调用nextLine()需先执行一次nextLine()吸收换行符。 - 资源关闭:
sc.close(),建议使用try-catch处理异常。 - 格式化输出:
System.out.printf("%.2f", d);
四、数组
1. 一维数组
- 声明:
int[] arr;(不能指定长度) - 创建:
arr = new int[5];→ 元素自动初始化为默认值[0,0,0,0,0] - 静态初始化:
int[] arr = {1,2,3};或new int[]{1,2,3} - 动态初始化:先声明后创建,再逐个赋值。
- 访问:索引从0开始,
arr[0],注意ArrayIndexOutOfBoundsException。 - 长度:
arr.length(不是方法)。
2. 多维数组(以二维为例)
int[][] matrix = new int[3][4]; // 规则3行4列
int[][] ragged = new int[3][]; // 不规则
ragged[0] = new int[2];
ragged[1] = new int[5];- 获取行数:
matrix.length,获取当前行列数:matrix[i].length。 - 遍历时注意每一行长度可能不同。
3. 数组操作
- 复制:
System.arraycopy()(原生高效)、Arrays.copyOf()、clone()。 - 排序:
Arrays.sort(arr)(Dual-Pivot Quicksort)、手写冒泡/选择/快排。 搜索:
- 线性搜索(未排序)。
- 二分搜索(已排序):
Arrays.binarySearch(arr, key),返回下标或负数插入点。
五、类与对象
1. 类的组成
- 实例变量/方法:属于对象,通过对象访问。
- 静态变量/方法:属于类,通过类名访问,不能直接访问实例成员。
- 构造函数:与类同名,无返回类型,可重载。一旦定义了有参构造,默认无参构造不再自动提供。
2. 封装
- 使用
private隐藏字段,提供public的 getter/setter。 - 保护内部实现,提供清晰的公共接口。
3. 方法
- 定义:
[修饰符] [static] 返回值 方法名(参数) { ... } 调用:
- 静态方法:
类名.方法名() - 实例方法:
对象.方法名()
- 静态方法:
参数传递:
- 基本类型:传值副本,不影响原变量。
- 引用类型:传引用副本,可修改对象内容,但不能改变原引用指向。
4. 构造方法链式调用
使用 this(参数) 调用同一类的另一个构造方法,必须是构造方法的第一条语句。
public class Person {
private String name;
public Person() {
this("Unknown");
}
public Person(String name) {
this.name = name;
}
}5. this 关键字
- 引用当前对象,用于区分成员变量和参数。
- 不能在静态上下文中使用。
this()必须是构造方法第一条语句。
6. 访问修饰符
| 修饰符 | 同类 | 同包 | 子类(不同包) | 任意 |
|---|---|---|---|---|
| private | ✔ | ✘ | ✘ | ✘ |
| default | ✔ | ✔ | ✘ | ✘ |
| protected | ✔ | ✔ | ✔ | ✘ |
| public | ✔ | ✔ | ✔ | ✔ |
7. 包(package)
- 文件第一行非注释代码:
package com.example.util; import语句位于package之后,类定义之前。- 静态导入:
import static java.lang.Math.PI;可直接使用PI。
六、继承
- 使用
extends关键字,Java 只支持单继承。 - 所有类隐式继承
Object。 方法重写(Override):
- 子类重新定义父类方法,方法签名必须相同。
- 使用
@Override注解。 - 访问修饰符不能比父类更严格(父类
protected→ 子类public可以,反之不行)。 - 返回类型可以是子类类型(协变返回)。
- 不能抛出比父类更宽泛的检查异常。
final方法不能被重写;static方法不能被重写(但可以隐藏);private方法不可见,不能重写。
- 重载(Overload):同一类中方法名相同,参数列表不同。
super 关键字:
- 调用父类构造方法:
super()必须是子类构造的第一条语句。 - 访问父类成员:
super.method()、super.field。 - 不能与
this()同时使用。
- 调用父类构造方法:
final 关键字
- final 类:不能被继承(如
String、Integer)。 - final 方法:不能被重写。
final 变量:
- 静态 final:声明时或静态代码块初始化。
- 实例 final:声明时或构造方法中初始化。
- 局部 final:使用前赋值即可。
- 参数 final:方法内不能修改参数值。
七、抽象类与接口
| 特性 | 抽象类(abstract class) | 接口(interface) |
|---|---|---|
| 关键字 | abstract class | interface |
| 继承/实现 | 单继承 | 多实现 |
| 构造方法 | 有 | 无 |
| 成员变量 | 可以是实例变量或常量 | 只能是 public static final 常量 |
| 方法 | 抽象方法 + 具体方法 | 抽象方法 + default/static 方法(JDK8+) |
| 访问修饰符 | 任意 | 方法默认 public abstract |
| 使用场景 | 代码复用、模板方法模式 | 定义规范、多继承能力 |
- 抽象类不能实例化,子类必须实现所有抽象方法(除非子类也是抽象类)。
- 接口中的
default方法提供默认实现,static方法属于接口本身。
八、多态
- 实现条件:继承 + 重写 + 父类引用指向子类对象。
- 编译时多态:方法重载。
- 运行时多态:通过父类引用调用被子类重写的方法,实际执行子类版本。
- 向上转型:
Parent p = new Child();安全,自动进行。 - 向下转型:
Child c = (Child) p;可能抛出ClassCastException,推荐先用instanceof检查。 instanceof:object instanceof ClassName返回true/false。- 用于类型检查,避免转换异常。
null instanceof X总是false。- 不能用于基本类型。
注意:静态方法、私有方法、构造方法不支持多态。
九、内部类与嵌套类
| 类型 | 关键字 | 能否访问外部类实例成员 | 持有外部类引用 | 能否定义静态成员 | 创建方式 |
|---|---|---|---|---|---|
| 成员内部类 | 无 | ✔ | ✔ | 不能(常量除外) | 外部类实例.new 内部类() |
| 静态嵌套类 | static | ✘(只能访问外部静态) | ✘ | ✔ | new 外部类.静态嵌套类() |
| 局部内部类 | 方法内 | ✔ | ✔ | 不能 | 在作用域内直接 new |
| 匿名类 | 无名字 | ✔ | ✔ | 不能 | new 接口/父类() { ... } |
- 内存泄漏风险:成员内部类隐式持有外部类引用,可能导致外部类无法被GC。
- 局部内部类访问局部变量:变量必须是
final或事实不可变(effectively final)。
十、枚举(Enum)
enum Color { RED, GREEN, BLUE }- 继承
java.lang.Enum,不能手动继承其他类。 常用方法:
name():返回常量名(如"RED")ordinal():返回索引(从0开始)toString():默认返回name()valueOf(String):根据名称获取枚举常量values():返回所有枚举常量的数组compareTo():比较顺序(基于ordinal)
避免在业务逻辑中使用 ordinal(),因为顺序改变会出错。可添加字段和构造方法来实现语义属性。十一、注解(Annotation)
- 内置注解:
@Override、@Deprecated、@SuppressWarnings、@SafeVarargs、@FunctionalInterface。 元注解(用于自定义注解):
@Retention:指定生命周期(SOURCE、CLASS、RUNTIME)@Target:指定可放置位置(TYPE、FIELD、METHOD、PARAMETER、CONSTRUCTOR等)@Documented:生成Javadoc时包含该注解@Inherited:允许子类继承父类的注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
String value() default "";
}十二、泛型
- 参数化类型:
List<String>保证类型安全,避免强制转换。 - 泛型类/接口:
class Box<T> { private T t; ... } - 泛型方法:
public <T> T getValue(T t) { return t; } 通配符:
?? extends T:上界通配符,用于读取(生产者)。? super T:下界通配符,用于写入(消费者)。- PECS原则:Producer Extends, Consumer Super。
- 有界类型参数:
<T extends Number>限定T必须是Number或其子类。
注意:泛型在编译时擦除,运行时无法获知具体类型参数。
十三、反射(Reflection)
获取
Class对象的三种方式:类名.class(编译时确定)对象.getClass()(运行时)Class.forName("全限定类名")(动态加载)
常用操作:
- 创建实例:
clazz.newInstance()或构造器newInstance() - 获取方法:
getMethod()、getDeclaredMethod() - 调用方法:
method.invoke(obj, args) - 访问字段:
getField()、setAccessible(true)
- 创建实例:
反射会破坏封装,带来性能开销,慎用。
十四、递归
- 定义:方法调用自身。
- 线性递归:每次调用一个子问题,深度 = 规模,时间复杂度 O(n)。
- 二分递归:每次调用两个子问题,如斐波那契
fib(n-1) + fib(n-2),存在重复计算,可优化(记忆化)。 - 注意防止栈溢出,确保有终止条件。
十五、String 字符串
- 不可变:任何修改都会产生新字符串对象。
- 字符串池:字面量
"abc"会放入常量池,复用相同内容;new String("abc")创建堆中新对象,不自动入池,可调用intern()手动入池。 常用方法:
length()、isEmpty()、isBlank()(Java 11+)indexOf()、lastIndexOf()equals()、equalsIgnoreCase()、compareTo()contains()、startsWith()、endsWith()substring()replace()、replaceAll()trim()、strip()(Java 11+)toUpperCase()、toLowerCase()split()、join()
- 高效拼接:使用
StringBuilder(线程不安全)或StringBuffer(线程安全)。
十六、代码最佳实践提示
- 使用括号明确运算优先级。
- 浮点数比较使用误差范围。
- 字符串内容比较用
equals()而非==。 - 关闭
Scanner资源,处理异常。 - 数组遍历注意边界,多用
length属性。 - 重写方法时加
@Override。 - 优先使用多态和接口而非
instanceof链。 - 枚举代替常量整数。
- 泛型提供编译时类型安全。
- 合理使用内部类,注意内存泄漏。
- 反射仅用于框架或特殊场景。
评论