02-Java基础语法

Java是强类型、面向对象的语言。语法简洁,自动内存管理,跨平台运行。

数据类型

基本数据类型

Java有8种基本类型,存储在栈上,传值。

// 整型
byte b = 127;           // 1字节,-128~127
short s = 32767;        // 2字节,-32768~32767
int i = 2147483647;     // 4字节(常用)
long l = 9223372036854775807L;  // 8字节,数字后加L

// 浮点型
float f = 3.14f;        // 4字节,7位精度,数字后加f
double d = 3.14159;     // 8字节,15位精度(默认)

// 字符型
char c = 'A';           // 2字节,Unicode字符

// 布尔型
boolean flag = true;    // true或false

常用类型:

  • 整数:int,大数:long

  • 小数:double

  • 字符:char,字符串:String

引用类型

引用类型存储对象引用(类似指针),包括类、接口、数组。

String str = "Hello";           // 字符串(不可变)
int[] arr = {1, 2, 3};          // 数组
Object obj = new Object();      // 对象
Integer num = 10;               // 包装类(自动装箱)

包装类

基本类型的对象封装,提供实用方法。

Byte, Short, Integer, Long      // 整型包装
Float, Double                    // 浮点包装
Character                        // 字符包装
Boolean                          // 布尔包装

// 自动装箱/拆箱(Java 5+)
Integer num = 10;                // 装箱:int -> Integer
int val = num;                   // 拆箱:Integer -> int

// 包装类方法
Integer.parseInt("123");         // 字符串转整数
Integer.toString(123);           // 整数转字符串
Integer.MAX_VALUE;               // 最大值
Double.isNaN(d);                 // 判断NaN

注意: 包装类是对象,可能为null;比较用 equals() 而非 ==

变量和常量

变量声明

int age = 25;                    // 声明并初始化
int height;                      // 仅声明
height = 180;                    // 后续赋值

var x = 10;                      // 类型推断(Java 10+)
var list = new ArrayList<String>();

常量

final int MAX = 100;             // final常量,不可修改
static final double PI = 3.14159; // 类常量

// 空白final(构造函数中初始化)
class Circle {
    private final double radius;
    
    public Circle(double r) {
        this.radius = r;  // 只能赋值一次
    }
}

运算符

算术运算符

+  -  *  /  %           // 加减乘除取模
++  --                  // 自增自减
+=  -=  *=  /=  %=      // 复合赋值

// 注意整数除法
int a = 5 / 2;          // 2(截断)
double b = 5.0 / 2;     // 2.5

比较运算符

==  !=  >  <  >=  <=    // 比较

// 注意:引用类型比较
String s1 = "hello";
String s2 = "hello";
s1 == s2;               // true(字符串常量池)
s1.equals(s2);          // true(内容相等,推荐)

String s3 = new String("hello");
s1 == s3;               // false(不同对象)
s1.equals(s3);          // true(内容相等)

逻辑运算符

&&  ||  !               // 与或非(短路)
&   |                   // 与或(不短路)

位运算符

&   |   ^   ~           // 按位与或异或取反
<<  >>  >>>             // 左移、算术右移、逻辑右移

特殊: Java的 >>> 是无符号右移,高位补0。

控制结构

条件语句

// if-else
if (condition) {
    // ...
} else if (condition2) {
    // ...
} else {
    // ...
}

// switch(支持String)
switch (value) {
    case "A":
        // ...
        break;
    case "B":
        // ...
        break;
    default:
        // ...
}

// switch表达式(Java 12+)
String result = switch (day) {
    case "MON", "TUE", "WED", "THU", "FRI" -> "Workday";
    case "SAT", "SUN" -> "Weekend";
    default -> "Invalid";
};

// 三元运算符
int max = (a > b) ? a : b;

循环语句

// for循环
for (int i = 0; i < n; i++) {
    // ...
}

// 增强for(foreach)
for (String item : list) {
    // ...
}

// while循环
while (condition) {
    // ...
}

// do-while循环
do {
    // ...
} while (condition);

跳转语句

break;              // 跳出循环
continue;           // 跳过本次迭代
return;             // 返回
// Java无goto

数组

一维数组

// 声明
int[] arr1;                      // 推荐写法
int arr2[];                      // C风格

// 创建
int[] arr = new int[5];          // 默认值0
int[] arr2 = {1, 2, 3, 4, 5};    // 初始化列表
int[] arr3 = new int[]{1, 2, 3}; // 显式创建

// 访问
arr[0] = 10;
int len = arr.length;            // 注意:length是属性,不是方法

// 遍历
for (int i = 0; i < arr.length; i++) {
    System.out.println(arr[i]);
}

for (int val : arr) {
    System.out.println(val);
}

多维数组

// 二维数组
int[][] matrix = new int[3][4];
int[][] matrix2 = {{1, 2}, {3, 4}, {5, 6}};

// 不规则数组
int[][] irregular = new int[3][];
irregular[0] = new int[2];
irregular[1] = new int[3];
irregular[2] = new int[1];

数组工具类

import java.util.Arrays;

int[] arr = {3, 1, 4, 1, 5};

// 排序
Arrays.sort(arr);                // {1, 1, 3, 4, 5}

// 二分查找(需要有序)
int index = Arrays.binarySearch(arr, 3);

// 填充
Arrays.fill(arr, 0);             // 全部填充为0

// 复制
int[] copy = Arrays.copyOf(arr, arr.length);

// 比较
boolean equal = Arrays.equals(arr1, arr2);

// 转字符串
String str = Arrays.toString(arr);  // [1, 1, 3, 4, 5]

字符串

String类

String是不可变对象,线程安全但每次修改创建新对象。

String s1 = "Hello";             // 字符串字面量(常量池)
String s2 = new String("Hello"); // 堆上创建新对象

// 常用方法
s1.length();                     // 长度
s1.charAt(0);                    // 获取字符
s1.substring(0, 3);              // 子串[0, 3)
s1.indexOf("ll");                // 查找位置
s1.contains("ell");              // 是否包含
s1.startsWith("He");             // 前缀
s1.endsWith("lo");               // 后缀
s1.toUpperCase();                // 转大写
s1.toLowerCase();                // 转小写
s1.trim();                       // 去空格
s1.replace("l", "L");            // 替换
s1.split(",");                   // 分割

// 拼接
String result = s1 + " " + s2;   // +运算符
String.join(", ", "a", "b", "c"); // join方法

StringBuilder

可变字符串,适合频繁修改,非线程安全。

StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
sb.insert(5, ",");               // 插入
sb.delete(5, 6);                 // 删除
sb.reverse();                    // 反转
String result = sb.toString();

// 性能对比
// String拼接1000次:~500ms(每次创建新对象)
// StringBuilder:~1ms(可变)

StringBuffer

线程安全的StringBuilder,性能略低。

StringBuffer sbf = new StringBuffer();
sbf.append("Thread-safe");

方法

方法定义

// 访问修饰符 返回类型 方法名(参数列表)
public int add(int a, int b) {
    return a + b;
}

// 无返回值
public void print(String msg) {
    System.out.println(msg);
}

// 可变参数
public int sum(int... numbers) {
    int total = 0;
    for (int num : numbers) {
        total += num;
    }
    return total;
}
sum(1, 2, 3, 4, 5);  // 可传任意个参数

方法重载

同名方法,不同参数。

public int max(int a, int b) {
    return a > b ? a : b;
}

public double max(double a, double b) {
    return a > b ? a : b;
}

public int max(int a, int b, int c) {
    return max(max(a, b), c);
}

注意: 返回值不同不构成重载,仅参数列表不同才行。

面向对象基础

类和对象

public class Person {
    // 成员变量(字段)
    private String name;
    private int age;
    
    // 构造函数
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // Getter
    public String getName() {
        return name;
    }
    
    // Setter
    public void setName(String name) {
        this.name = name;
    }
    
    // 方法
    public void introduce() {
        System.out.println("I'm " + name + ", " + age + " years old.");
    }
}

// 创建对象
Person p = new Person("Alice", 25);
p.introduce();

访问修饰符

public      // 所有类可访问
protected   // 同包+子类可访问
默认()     // 同包可访问
private     // 仅本类可访问

static关键字

public class Counter {
    private static int count = 0;  // 静态变量(类变量)
    
    public Counter() {
        count++;
    }
    
    public static int getCount() {  // 静态方法
        return count;
    }
}

// 使用
Counter c1 = new Counter();
Counter c2 = new Counter();
System.out.println(Counter.getCount());  // 2

常见陷阱

// 1. == vs equals
String s1 = "hello";
String s2 = new String("hello");
s1 == s2;               // false(引用不同)
s1.equals(s2);          // true(内容相同)

// 2. 数组越界
int[] arr = new int[5];
arr[5] = 10;            // ArrayIndexOutOfBoundsException

// 3. 空指针
String s = null;
s.length();             // NullPointerException

// 4. 整数除法
int a = 5 / 2;          // 2(不是2.5)

// 5. switch缺少break
switch (x) {
    case 1:
        System.out.println("One");
        // 没有break,会穿透到case 2
    case 2:
        System.out.println("Two");
        break;
}

输入输出

控制台输入输出

import java.util.Scanner;

// 输出
System.out.println("Hello");     // 带换行
System.out.print("World");       // 不换行
System.out.printf("Age: %d\n", 25);  // 格式化

// 输入
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();     // 读整数
double d = scanner.nextDouble(); // 读浮点数
String line = scanner.nextLine(); // 读一行
scanner.close();

文件输入输出

import java.io.*;

// 写文件
try (PrintWriter writer = new PrintWriter("output.txt")) {
    writer.println("Hello, File!");
} catch (IOException e) {
    e.printStackTrace();
}

// 读文件
try (BufferedReader reader = new BufferedReader(new FileReader("input.txt"))) {
    String line;
    while ((line = reader.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}

异常处理

try-catch-finally

try {
    int result = 10 / 0;
} catch (ArithmeticException e) {
    System.out.println("Division by zero: " + e.getMessage());
} catch (Exception e) {
    System.out.println("General exception: " + e.getMessage());
} finally {
    // 总是执行(清理资源)
    System.out.println("Cleanup");
}

try-with-resources(推荐)

自动关闭资源,适用于实现 AutoCloseable 的类。

// Java 7+
try (FileReader fr = new FileReader("file.txt");
     BufferedReader br = new BufferedReader(fr)) {
    String line = br.readLine();
} catch (IOException e) {
    e.printStackTrace();
}
// 自动调用close(),无需finally

抛出异常

public void divide(int a, int b) {
    if (b == 0) {
        throw new IllegalArgumentException("Divisor cannot be zero");
    }
    return a / b;
}

// 声明抛出
public void readFile() throws IOException {
    FileReader fr = new FileReader("file.txt");
    // ...
}

最佳实践

  1. 使用final:不变的变量用final

  2. 优先局部变量:缩小作用域

  3. 避免魔法数字:用常量代替

  4. null检查:访问对象前判空

  5. 关闭资源:用try-with-resources

  6. StringBuilder拼接:循环中拼接字符串

  7. equals比较对象:引用类型用equals

  8. 包装类慎用==:可能缓存失效

  9. 异常分类:可恢复用检查异常,不可恢复用运行时异常

  10. 遵循命名规范:提高可读性

核心: Java强调安全性和可维护性,利用语言特性写清晰健壮的代码。