Java 语法基础

JDK 的组成

  • JVM(Java 虚拟机):一种能将编译后的 Java 字节码(.class 文件)加载、验证、解释或即时编译并执行的抽象计算机环境。
  • JRE(Java 运行时环境):包含 JVM、核心类库和其他必需组件,用于在本地系统上运行 Java 应用程序的完整环境。
  • JDK(Java 开发工具包):在 JRE 基础上额外提供 Java 编译器(javac)、调试器等开发工具,用于编写和调试 Java 程序的套件。

注释类型

  1. 单行注释(Single-line Comment)
    // 开头,直到行尾都被视为注释。

    1
    2
    // 这是一个单行注释
    int x = 10; // 也可以放在代码行末
  2. 多行注释(Block Comment)
    /* 开始,以 */ 结束,适合注释多行内容。

    1
    2
    3
    4
    5
    /*
    * 这是一个多行注释
    * 可以覆盖多行文字
    */
    int y = 20;
  3. 文档注释(Javadoc Comment)
    /** 开始,以 */ 结束,通常用于生成 API 文档,可放在类、方法、字段等声明之前。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    /**
    * 计算两个整数的和。
    *
    * @param a 第一个加数
    * @param b 第二个加数
    * @return 返回 a 与 b 的和
    */
    public int add(int a, int b) {
    return a + b;
    }

字面量

  1. 整数字面量(Integer Literals)
    • 十进制123, 0
    • 八进制(以 0 开头):075(等于十进制 61)
    • 十六进制(以 0x0X 开头):0xFF, 0X1A3
    • 二进制(Java 7+,以 0b0B 开头):0b1010, 0B1101
    • 长整型后缀:在数字后加 Ll,如 12345678901L
  2. 浮点数字面量(Floating-Point Literals)
    • 十进制形式3.14, 0.001, 2.
    • 科学计数法1.23e3 (×10³), 4.56E-2 (×10⁻²)
    • 单精度后缀:在数字后加 Ff,如 3.14F
    • 双精度默认:如 2.71828(等同于 2.71828D
  3. 字符字面量(Character Literals)
    • 单引号括起的单个字符:'a', '中', '$'
    • 支持转义序列:\n, '\u4E2D', '\''
  4. 字符串字面量(String Literals)
    • 双引号括起的字符序列:"Hello, Java!", "换行:\n下一行"
    • 支持所有字符转义:\t, \", \\
  5. 布尔字面量(Boolean Literals)
    • 只有两个取值:truefalse
  6. 空字面量(Null Literal)
    • 用于表示引用类型不指向任何对象:null

变量声明

1
[修饰符列表] 数据类型 变量名 [= 初始值] [, 变量名 [= 初始值] …] ;

变量修饰符

  • package-private(默认)
    不加任何访问修饰符时,称为包级私有。变量只对同一包内的类可见,包外不可访问。

  • public
    公开访问权限,声明为 public 的变量对所有类可见,无论是否在同一包中。

  • protected
    受保护访问权限,声明为 protected 的变量对同一包内的类及所有子类可见(即使子类在不同包中)。

  • private
    私有访问权限,声明为 private 的变量仅在当前类内部可见,外部类和子类均无法直接访问。

  • static
    静态变量属于类本身而非某个实例。所有对象共享同一份 static 变量,且可以通过 ClassName.var 直接访问。

  • final
    常量修饰符,声明后必须在定义处或构造器中赋值,且赋值一次后不可再修改,常用于定义不可变值。

  • transient
    瞬态修饰符,指示该变量在对象序列化(Serializable)时不被持久化写入序列化流。

  • volatile
    易变修饰符,保证多个线程访问该变量时的可见性和有序性:对一个线程写入的值,其他线程能立即看到,不会被线程本地缓存长期“隐藏”。

存储区域

  • 局部变量 → 线程栈;实例变量 → 堆;静态变量 → 方法区。

基本类型 vs 引用类型

  • 基本类型存值;引用类型存地址,实际对象在堆上。

变量访问

  • 字节码通过 load/store(局部变量)和 get/put(实例/静态变量)在操作数栈与内存区间搬运数据。

并发可见性

  • 每线程独立栈;堆与方法区共享;volatilesynchronized 保证跨线程可见性与有序性。

生命周期

  • 栈上随方法调用进出;静态随类加载/卸载;堆上随对象引用消失由 GC 回收。

自动类型转换

  • 数值类型“向上”转换:编译器自动将容量小的类型提升到容量大的类型,顺序为
    byte → short → int → long → float → double,并且在算术运算中,byte/short/char 会先提升为 int
  • char 到整数char 可自动转为 int 及更大类型。
  • 引用类型“向上”转型:子类对象可赋给父类引用,无需显式转换。
  • 限制:只能“扩宽”或“子 → 父”,反之(“窄化”或“父 → 子”)必须显式强制转换。

强制类型转换

  1. 基本类型转换

    • 窄化转换(大 → 小):需 (目标类型) 值,可能截断或溢出。

      1
      2
      int i = (int) 3.9;    // i = 3
      byte b = (byte) 130; // b = -126
    • 拓宽转换(小 → 大):自动完成,无需显式。

  2. 引用类型转换

    • 上转型(子 → 父):隐式安全。

      1
      Animal a = new Dog();
    • 下转型(父 → 子):需 (子类) 父引用,若类型不符抛 ClassCastException

      1
      2
      3
      if (a instanceof Dog) {
      Dog d = (Dog) a;
      }
  3. 常见注意点

    • 混合运算:整型运算默升为 int,赋小类型需显式转。
    • 精度控制:如 (double) a / b 保留小数。
    • 泛型前代码:对 Object 集合取出时需要转换,推荐使用泛型避免。

要点:大 → 小要显式转换并谨防数据丢失;父 → 子要确认类型再转。

运算符

  1. 算术运算符

    • +-*/%
    • 自增/自减:++aa++--aa--
  2. 赋值运算符

    • 简单赋值:=
    • 复合赋值:+=-=*=/=%=&=|=^=<<=>>=>>>=
  3. 关系(比较)运算符

    • ==!=
    • ><>=<=
  4. 逻辑运算符

    • 与:&&(短路),&(非短路)
    • 或:||(短路),|(非短路)
    • 非:!
  5. 位运算符

    • 与:&
    • 或:|
    • 异或:^
    • 取反:~
  6. 位移运算符

    • 左移:<<
    • 右移(带符号):>>
    • 右移(无符号):>>>
  7. 三元运算符

    • condition ? expr1 : expr2
    1
    int max = (a > b) ? a : b;
  8. 其他运算符

    • 类型检查instanceof
    • 数组下标[]
    • 方法调用()
    • 成员访问.->(仅用于 JNI)
    • 强制类型转换(Type) value

提示:运算符优先级影响表达式计算顺序,可参考官方文档或使用括号 () 来明确运算顺序。

程序流程控制

  1. 顺序执行
    按代码书写顺序从上到下依次执行。

  2. 分支(选择)

    • if / if–else / if–else if–else

      1
      2
      3
      if (cond) { … }
      else if (cond2) { … }
      else { … }
    • switch

      1
      2
      3
      4
      5
      switch (expr) {
      case 常量1: …; break;
      case 常量2: …; break;
      default: …;
      }
  3. 循环(迭代)

    • for 循环

      1
      2
      3
      for (初始化; 条件; 更新) {

      }
    • **增强型 for**(遍历数组/集合)

      1
      2
      3
      for (Type item : collection) {

      }
    • while 循环

      1
      2
      3
      while (条件) {

      }
    • do–while 循环

      1
      2
      3
      do {

      } while (条件);
  4. 跳转控制

    • break:退出最近的 switch 或循环
    • continue:跳过本次循环、进入下一次迭代
    • return:结束方法并可返回值
  5. 异常处理

    • 捕获/处理try–catch–finally

      1
      2
      3
      4
      5
      6
      7
      try {

      } catch (ExceptionType e) {

      } finally {

      }
    • 抛出异常throw new ExceptionType("msg");

要点

  • 用分支 (if/switch) 做条件判断,
  • 用各种 for/while 循环重复执行,
  • 配合 break/continue 控制循环流程,
  • 用异常 (try–catch) 管理错误场景。

数组

1. 数组的定义

  • 一维数组

    1
    2
    3
    4
    5
    6
    // 声明
    int[] arr1;
    String arr2[];
    // 分配空间并初始化
    arr1 = new int[5];
    String[] arr3 = new String[] { "A", "B", "C" };
  • 多维数组

    1
    2
    3
    4
    5
    6
    // 二维数组
    int[][] matrix = new int[3][4];
    // 不规则二维数组
    int[][] ragged = new int[3][];
    ragged[0] = new int[2];
    ragged[1] = new int[5];

2. 数组的遍历

  • 传统 for 循环

    1
    2
    3
    for (int i = 0; i < arr.length; i++) {
    System.out.println(arr[i]);
    }
  • 增强型 for(foreach)

    1
    2
    3
    for (String s : arr) {
    System.out.println(s);
    }
  • while / do–while

    1
    2
    3
    4
    int i = 0;
    while (i < arr.length) {
    System.out.println(arr[i++]);
    }

3. 存储原理

  1. 连续内存
    数组在内存中占用一段连续空间,每个元素大小相同(基于元素类型)。

  2. 索引访问
    通过索引直接计算元素地址:

    1
    元素地址 = 数组基地址 + 索引 * 元素字节长度
  3. 定长特性
    数组长度在创建时确定,无法动态扩容;要变更长度需新建数组并复制元素。

  4. 多维数组
    Java 多维数组本质是“数组的数组”,最外层引用指向若干子数组,它们可分别分配内存(支持不规则矩阵)。

要点

  • 定义:用 new Type[size] 创建定长、同类型的存储结构;
  • 遍历:常用 for / 增强 for
  • 存储:连续内存+索引直接定位,访问高效但尺寸固定。

方法

  • 定义

    1
    2
    3
    4
    // 语法:[修饰符] 返回类型 方法名(参数列表) { 方法体 }
    public int add(int x, int y) {
    return x + y;
    }
  • 执行原理

    1. 调用时在栈上为方法创建栈帧(包含局部变量、操作数栈等)。
    2. 执行方法体指令,使用操作数栈进行计算。
    3. return 弹出栈帧,将返回值(若有)传给调用者。
  • 参数传递

    • 基本类型:按值传递,方法内修改不影响外部变量。
    • 引用类型:传递的是引用的副本(引用按值传)。方法内可通过该引用修改对象内容,但无法让引用指向新对象影响外部。
  • 重载(Overload)

    • 同一类中多个同名方法,参数列表(类型、个数、顺序)必须不同。
    • 编译期根据调用时的静态类型和实际参数匹配最优方法签名。
    • 与返回类型、抛出异常无关。