01-Java基础语法
侧边栏壁纸
  • 累计撰写 40 篇文章
  • 累计收到 1 条评论

01-Java基础语法

ASN__
2026-06-22 / 0 评论 / 4 阅读 / 正在检测是否收录...

1.1 基本数据类型

Java 是一门强类型语言,共有 8 种基本数据类型(Primitive Type)分为三大类:数值型(整型,浮点型)、字符型和布尔型

类型总览

分类类型字节数取值范围默认值备注
整型byte1-128 ~ 1270
整型short2-32768 ~ 327670
整型int4-2^31 ~ 2^31-10默认整数类型
整型long8-2^63 ~ 2^63-10L字面量需加 L 后缀
浮点型float4±3.4E-38 ~ ±3.4E+380.0f字面量需加 f 后缀
浮点型double8±1.7E-308 ~ ±1.7E+3080.0d默认浮点类型
字符型char20 ~ 65535 (Unicode)'\u0000'表示单个 Unicode 字符
布尔型boolean1位true / falsefalseJVM 中通常用 int 表示

代码示例

public class PrimitiveTypes {
    public static void main(String[] args) {
        // 整型
        byte b = 100;               // 1字节
        short s = 10000;            // 2字节
        int i = 100000;             // 4字节,默认
        long l = 10000000000L;      // 8字节,必须加 L 后缀

        // 浮点型
        float f = 3.14f;            // 4字节,必须加 f 后缀
        double d = 3.1415926535;    // 8字节,默认

        // 字符型
        char c1 = 'A';              // 2字节
        char c2 = '\u0041';         // Unicode 编码表示 'A'
        char c3 = 65;               // ASCII 码表示 'A'

        // 布尔型
        boolean flag = true;
    }
}

注意事项

  • long 和 float 的字面量后缀不可省略:不加 L 的整数字面量默认是 int,不加 f 的浮点字面量默认是 double
  • char 可以存中文:因为 char 是 2 字节 Unicode,一个中文字符正好是 2 字节。
  • boolean 占用空间:JVM 规范中 boolean 被当作 int 处理(4字节),但在 boolean 数组中每个元素占用 1 字节。
  • 默认值仅对成员变量有效:局部变量必须显式初始化,否则编译不通过。
public class DefaultValues {
    // 实例变量:自动初始化为默认值
    byte b;       // 0
    short s;      // 0
    int i;        // 0
    long l;       // 0L
    float f;      // 0.0f
    double d;     // 0.0d
    char c;       // '\u0000'
    boolean flag; // false

    public void test() {
        int local;  // 局部变量
        // System.out.println(local); // 编译错误!未初始化
    }
}

1.2 变量类型

Java 中有三种变量,按声明位置和修饰符区分。

对比总览

变量类型声明位置生命周期默认值存储位置修饰符
局部变量方法、构造方法或代码块中方法执行期间无,必须显式初始化栈内存(方法栈帧)只能用 final
实例变量类中、方法外与对象共存亡有默认值堆内存(对象中)访问控制修饰符
类变量(静态变量)类中、方法外,static 修饰类加载时创建,类卸载时销毁有默认值方法区/元空间static + 访问控制修饰符

内存模型 JDK8+

┌─────────────────────────────────────────────┐
│                  JVM 内存结构                  │
├───────────────┬───────────────┬─────────────┤
│    虚拟机栈    │    堆内存      │   方法区     │
│   (Stack)     │   (Heap)      │ Metaspace(元空间) │
├───────────────┼───────────────┼─────────────┤
│ 方法栈帧       │ 对象实例       │ 类元信息(类结构、字段、方法字节码) │
│ 局部变量表     │ 数组          │ 运行时常量池、符号表、Vtable虚方法表 │
│ 操作数栈       │ 实例变量       │ 即时编译代码、类加载信息            │
│ 方法返回地址   │ Class对象、静态变量、字符串常量池 │
│ 动态链接       │               │
│ 线程私有       │ 线程共享       │ 线程共享      │
└───────────────┴───────────────┴─────────────┘
运行时常量池 → 永远在元空间(方法区)

方法栈帧:每调用一个方法,就会在虚拟机栈创建一块独立内存 = 栈帧 
如调用 sayHello() → 生成 sayHello() 栈帧 调用 main() → 生成 main() 栈帧 方法执行完,栈帧直接弹出销毁。

局部变量表存放:局部变量、方法参数、对象引用

操作数栈:JVM 运算专用临时空间,做加减、赋值、打印时中转数据

方法返回地址: 方法执行完后,要回到调用处继续执行,记录跳转位置。

动态链接:栈帧保存符号引用,运行时把符号引用解析成真实内存地址
比如代码里 System.out.println,编译时只是符号,运行时动态找到对应方法地址。


对象实例:new User("张三") 在堆中创建一块内存,就是 User 对象实例

数组:所有数组无论基本类型还是引用类型,本体都在堆。

实例变量:属于单个对象,存在对应对象实例内部

Class 对象、静态变量,每个类在堆里唯一存在一个 Class 对象 User.class静态变量 school 不归属任何实例,存在堆的 User.class 对象中:

字符串常量池
"北大" "张三" "李四" 这类双引号字面量,存放在堆的 StringTable 字符串常量池

元空间(方法区)只存类模板,不存对象数据
类元信息 (类结构、字段、方法字节码)编译后 User.class 文件里的固定模板,加载后放入元空间


 运行时常量池、符号表:运行时常量池:class 文件自带常量池加载进来,存数字、符号引用
符号表:记录类名、方法名、字段名等符号,供动态链接使用

 Vtable 虚方法表:存放当前类所有重写 / 继承的虚方法地址,多态调用时快速查找方法。
比如如果 User 有父类,重写 toString (),虚表会记录 toString 的内存地址

即时编译代码(JIT)
热点方法被多次调用,JIT 把字节码编译成本地机器码,缓存到元空间,提升执行速度
类加载信息
记录当前类由哪个类加载器加载、父类、接口、访问权限等元数据。



栈:方法执行现场,无对象本体
堆:所有对象、数组、静态变量、字符串池
元空间:类的模板定义(只存描述,不存数据值)
通俗总览
      栈管运行(方法调用),堆管存储(对象、静态数据),元空间管类模板(类定义信息)
栈内存 (Stack) —— 线程的 “执行剧本”
      核心职责:存储每个方法调用对应的栈帧,描述方法执行过程
      存储内容:局部变量表(基本类型、对象引用)、操作数栈、方法返回地址、动态链接
      生命周期:方法调用创建栈帧,方法执行完毕立刻销毁,随线程生随灭
      内存分配:连续内存,栈大小固定(可通过 -Xss 设置)
      线程模型:线程私有,天然线程安全,不存在并发竞争
      补充:不存储方法代码,方法字节码存在元空间
堆内存 (Heap) —— GC 的 “主战场”
      核心职责:存储运行时动态创建的数据,所有 new 出来的对象、数组
      存储内容:实例对象、数组、实例变量、Class 对象、静态变量、字符串常量池
      生命周期:对象无有效引用后等待 GC 回收,存活时间不确定
      内存分配:非连续内存,动态扩展;-Xms 初始堆,-Xmx 最大堆,是 JVM 最大内存区域
      线程模型:线程共享,存在线程安全问题;通过 TLAB 线程本地分配缓冲区优化并发分配
方法区 / 元空间 (Method Area / Metaspace) —— 类的 “档案馆”
      核心职责:存储类元信息(类结构、字段、方法字节码)、运行时常量池、符号引用
      版本重大变化(Java 8):
      彻底移除永久代(PermGen),改用元空间 Metaspace
      元空间使用本地内存(Native Memory),不再占用 JVM 堆内存
      JDK7 起就将静态变量、字符串常量池移出永久代,放入堆内存
      生命周期:类加载时创建类元数据,类完全卸载(ClassLoader 被回收)才释放
      线程模型:线程共享,类加载、反射访问需要保证线程安全
      典型异常:OutOfMemoryError: Metaspace,加载类过多耗尽本地内存
      GC 特点:回收频率极低,仅 Full GC 时尝试卸载无用类、回收废弃常量


混淆
      局部变量 → 虚拟机栈
      实例变量 → 堆(对应实例对象内部)
      静态变量 → JDK7+ 堆(Class 对象末尾)
      方法代码、类结构 → 元空间
      运行时常量池 → 元空间
      字符串常量池 (StringTable) → JDK7+ 堆
      Class反射对象 → 堆;描述这个类的元数据 → 元空间


快速记忆:
栈:线程私有,存局部变量、方法执行现场,用完即销毁,无 GC
堆:GC 主战场,所有对象、数组、静态变量、字符串池,线程共享
元空间:方法区新实现,本地内存,只存类的模板信息,不存对象数据

代码示例

public class VariableTypes {
    // 类变量(静态变量)
    static int staticVar = 100;
    static final String CONSTANT = "常量";

    // 实例变量
    int instanceVar = 200;
    String name;

    public void method(int param) {   // param 也是局部变量
        // 局部变量
        int localVar = 300;
        String localStr;

        // System.out.println(localStr); // 编译错误!未初始化

        System.out.println(localVar);       // 300
        System.out.println(instanceVar);    // 200
        System.out.println(staticVar);      // 100

        {
            // 代码块中的局部变量
            int blockVar = 400;
            System.out.println(blockVar);
        }
        // System.out.println(blockVar); // 编译错误!超出作用域
    }
}

注意事项

  • 局部变量必须显式初始化,否则编译报错。
  • 实例变量的默认值可以依赖,但不推荐 —— 显式初始化是良好习惯。
  • 静态变量在类加载时初始化,只会初始化一次,所有实例共享。
  • JDK 8 之后,方法区被元空间(Metaspace)取代,使用本地内存,不再受 JVM 堆大小限制。

1.3 运算符

运算符分类

算术运算符

运算符含义示例
+加 / 字符串拼接a + b
-a - b
*a * b
/a / b
%取模(取余)a % b
++自增a++++a
--自减a----a

关系运算符(比较运算符)

运算符含义结果类型
==等于boolean
!=不等于boolean
>大于boolean
<小于boolean
>=大于等于boolean
<=小于等于boolean

逻辑运算符

运算符含义短路特性
&&逻辑与是(左边为 false 时不执行右边)
` `逻辑或是(左边为 true 时不执行右边)
!逻辑非
&按位与 / 非短路逻辑与
``按位或 / 非短路逻辑或

位运算符

运算符含义
&按位与
``按位或
^按位异或
~按位取反
<<左移
>>右移(带符号)
>>>无符号右移

赋值运算符

=+=-=*=/=%=&=|=^=<<=>>=>>>=

运算符优先级

优先级运算符结合性
() [] .
! ~ ++ --
* / %
+ -
<< >> >>>
< <= > >= instanceof
== !=
&
^
``
&&
` `
?:(三元)
= += 等赋值运算符

记忆口诀:乘除 > 加减 > 比较 > 逻辑 > 赋值

字符串比较:== vs equals()

String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");

System.out.println(s1 == s2);       // true  (同一字符串池对象)
System.out.println(s1 == s3);       // false (不同对象)
System.out.println(s1.equals(s3));  // true  (内容相同)

最佳实践

// 1. 使用括号明确优先级
int result = (a + b) * c / (d - e);  // 清晰

// 2. 浮点数比较使用误差范围
double x = 0.1 + 0.2;
double y = 0.3;
if (Math.abs(x - y) < 1e-10) {       // 正确做法
    System.out.println("相等");
}
// if (x == y) { ... }               // 错误!可能不相等

// 3. 避免在复杂表达式中使用自增自减
int i = 5;
int j = i++ + ++i;  // 难以理解,避免使用
// 建议分开写:
i++;
int k = i;
i++;
j = k + i;

// 4. 短路求值的妙用
if (obj != null && obj.getValue() > 0) {  // 安全:先判空
    // ...
}

1.4 类型转换

自动类型转换(隐式转换)

规则:小范围类型自动转换为大范围类型,不会丢失精度。

byte → short → int → long → float → double
         char  ↗
byte b = 10;
short s = b;      // byte → short,自动
int i = s;        // short → int,自动
long l = i;       // int → long,自动
float f = l;      // long → float,自动(但可能损失精度!)
double d = f;     // float → double,自动

char c = 'A';
int ci = c;       // char → int,自动(ci = 65)
注意long(8字节)转 float(4字节)虽然范围更大,但可能损失精度,因为 float 的有效位数(约7位)不如 long(19位)。

强制类型转换(显式转换)

规则:大范围类型转为小范围类型,需要使用强制转换符,可能丢失数据。

double d = 3.99;
int i = (int) d;       // i = 3,小数部分被截断(不是四舍五入)

long l = 300L;
byte b = (byte) l;     // b = 44,高位被截断,结果不可预测

// 溢出示例
int big = 130;
byte small = (byte) big;  // small = -126(byte 范围 -128~127,溢出循环)

包装类与自动装箱/拆箱

// 自动装箱:基本类型 → 包装类
Integer a = 10;           // 等价于 Integer.valueOf(10)
Double d = 3.14;          // 等价于 Double.valueOf(3.14)

// 自动拆箱:包装类 → 基本类型
int b = a;                // 等价于 a.intValue()
double e = d;             // 等价于 d.doubleValue()

// 混合运算时自动拆箱
Integer x = 100;
Integer y = 200;
int sum = x + y;          // 自动拆箱后计算

Integer 缓存机制

Integer i1 = 127;
Integer i2 = 127;
System.out.println(i1 == i2);   // true(缓存范围内,同一对象)

Integer i3 = 128;
Integer i4 = 128;
System.out.println(i3 == i4);   // false(超出缓存范围,不同对象)

// 正确的比较方式
System.out.println(i3.equals(i4));  // true
Integer 默认缓存 -128127 之间的值(上限可通过 -XX:AutoBoxCacheMax 调整)。

字符串与基本类型的转换

// 字符串 → 基本类型
int i = Integer.parseInt("123");
double d = Double.parseDouble("3.14");
boolean b = Boolean.parseBoolean("true");

// 基本类型 → 字符串
String s1 = String.valueOf(123);
String s2 = Integer.toString(456);
String s3 = 789 + "";              // 简单但不推荐
String s4 = String.format("%d", 100);

1.5 数组

数组特点

  • 类型统一:所有元素必须是同一类型
  • 长度固定:创建后不可改变长度
  • 索引访问:从 0 开始,最大为 length - 1
  • 连续存储:内存中连续分配,支持高效随机访问

声明与创建

// 声明(不能指定长度!)
int[] arr1;                // 推荐写法 类型[] 变量名
int arr2[];                // C 风格,不推荐

// 创建(必须指定长度)
arr1 = new int[5];         // 所有元素初始化为 0
String[] strs = new String[3];  // 所有元素初始化为 null

// 声明+创建一步完成
double[] nums = new double[10];

静态初始化

// 方式一:简写形式
int[] arr1 = {1, 2, 3, 4, 5};

// 方式二:完整形式
int[] arr2 = new int[]{1, 2, 3, 4, 5};

// 注意:简写形式只能用于声明时。不能单独用在赋值语句里。
// int[] arr3;
// arr3 = {1, 2, 3};      // 编译错误!
// int[] arr3 = {1,2,3} 
//不然就老老实实  new int[]
int[] arr3;
arr3 = new int[]{1, 2, 3};  // 正确

多维数组

// 规则二维数组(3行4列)
int[][] matrix = new int[3][4];
matrix[0][0] = 1;
matrix[2][3] = 12;

// 静态初始化二维数组
int[][] grid = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};

// 不规则数组(每行长度不同)
int[][] jagged = new int[3][];
jagged[0] = new int[2];
jagged[1] = new int[4];
jagged[2] = new int[3];

数组操作

遍历

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

// 方式一:for 循环(有索引)
for (int i = 0; i < arr.length; i++) {
    System.out.println(arr[i]);
}

// 方式二:for-each(简洁,无索引)
for (int value : arr) {
    System.out.println(value);
    // 注意:修改 value 不会影响原数组!
}

复制(重点)

//这三种方法对数组本身执行的都是浅拷贝
int[] src = {1, 2, 3, 4, 5};

// 方式一:手动循环
int[] dest1 = new int[src.length];
for (int i = 0; i < src.length; i++) {
    dest1[i] = src[i];
}

// 方式二:System.arraycopy()(最高效) (速度最快,native方法,直接操作内存)
int[] dest2 = new int[src.length];
System.arraycopy(src, 0, dest2, 0, src.length);

// 方式三:Arrays.copyOf()(最简洁)  利用 System.arraycopy(),可指定新数组长度。
int[] dest3 = Arrays.copyOf(src, src.length);

// 方式四:数组.clone()
int[] dest4 = src.clone();

排序

int[] arr = {5, 2, 8, 1, 9};

// Arrays.sort()(双轴快速排序,O(n log n))
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));  // [1, 2, 5, 8, 9]

// 部分排序
Arrays.sort(arr, 1, 4);  // 只排序索引 [1, 4) 的元素

// 冒泡排序(手写版,O(n²))
void bubbleSort(int[] arr) {
    for (int i = 0; i < arr.length - 1; i++) {
        for (int j = 0; j < arr.length - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

// 选择排序(手写版,O(n²))
void selectionSort(int[] arr) {
    for (int i = 0; i < arr.length - 1; i++) {
        int minIdx = i;
        for (int j = i + 1; j < arr.length; j++) {
            if (arr[j] < arr[minIdx]) {
                minIdx = j;
            }
        }
        int temp = arr[i];
        arr[i] = arr[minIdx];
        arr[minIdx] = temp;
    }
}

搜索

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

// 线性搜索 O(n)
int linearSearch(int[] arr, int target) {
    for (int i = 0; i < arr.length; i++) {
        if (arr[i] == target) return i;
    }
    return -1;
}

// 二分搜索 O(log n)(前提:数组必须有序)
int index = Arrays.binarySearch(arr, 5);  // 返回 2
int notFound = Arrays.binarySearch(arr, 4); // 返回 -3(-(插入点) - 1)

注意事项

  • arr.length 获取长度,是属性不是方法(区别于 String.length())。
  • for-each 中修改临时变量不影响原数组,需要修改元素请使用普通 for 循环。
  • 遍历时不能修改数组结构(增删元素),但普通 for 循环中修改已有元素是可以的。
  • 数组越界:访问 arr[arr.length] 会抛出 ArrayIndexOutOfBoundsException

1.6 String 字符串

核心特点

  • 不可变(Immutable)Stringfinal 类,一旦创建内容不可改变。
  • 线程安全:不可变性天然保证线程安全。
  • 字符串池(String Pool):JVM 维护一个字符串常量池,相同字面量复用同一对象。

创建方式

// 方式一:字面量(进入字符串池)
String s1 = "Hello";

// 方式二:new(不进入字符串池,在堆中创建新对象)
String s2 = new String("Hello");

// 方式三:字符数组
char[] chars = {'H', 'e', 'l', 'l', 'o'};
String s3 = new String(chars);

// 验证
System.out.println(s1 == s2);  // false
System.out.println(s1 == s3);  // false
System.out.println(s1.equals(s2));  // true

常用方法

String str = " Hello World ";

// 长度和判空
str.length();                    // 13(包含两边空格)
str.isEmpty();                   // false
str.isBlank();                   // false(JDK 11+,只判断是否空白字符)

// 查找
str.indexOf('o');                // 5(首次出现位置)
str.indexOf("World");            // 7
str.lastIndexOf('o');            // 8

// 比较
str.equals("Hello");             // false
str.equalsIgnoreCase(" hello world ");  // true
str.compareTo("ABC");            // 字典序比较

// 判断前缀后缀
str.startsWith(" He");           // true
str.endsWith("d ");              // true
str.contains("Wo");              // true

// 截取
str.substring(1, 6);             // "Hello"([1, 6) 左闭右开)

// 替换
str.replace('l', 'L');           // " HeLLo WorLd "
str.replace("Hello", "Hi");      // " Hi World "
str.replaceAll("\\s", "_");      // "_Hello_World_"(正则替换)

// 去空格
str.trim();                      // "Hello World"(去掉首尾半角空格)
str.strip();                     // "Hello World"(JDK 11+,支持全角空格)

// 大小写
str.toUpperCase();               // " HELLO WORLD "
str.toLowerCase();               // " hello world "

// 分割与拼接
String[] parts = "a,b,c".split(",");   // ["a", "b", "c"]
String joined = String.join("-", "A", "B", "C");  // "A-B-C"

intern() 方法

String s1 = new String("hello");
String s2 = "hello";
System.out.println(s1 == s2);         // false

String s3 = s1.intern();              // 将 s1 的内容加入字符串池
System.out.println(s3 == s2);         // true

StringBuilder vs StringBuffer vs String

特性StringStringBuilderStringBuffer
可变性不可变可变可变
线程安全安全(不可变)不安全安全(synchronized)
性能拼接时最慢(频繁创建新对象)最快较快
适用场景少量字符串操作单线程频繁修改多线程频繁修改
// StringBuilder 示例(推荐单线程下使用)
StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
sb.insert(5, ",");              // "Hello, World"
sb.replace(0, 5, "Hi");        // "Hi, World"
sb.delete(4, 5);                // "Hi, World"
sb.reverse();                   // "dlroW ,iH"
String result = sb.toString();

// StringBuffer 示例(多线程安全)
StringBuffer sbf = new StringBuffer();
sbf.append("Thread-safe");

频繁拼接的性能对比

// 低效方式:每次 + 都创建新的 String 对象
String s = "";
for (int i = 0; i < 10000; i++) {
    s += i;  // 创建 10000 个临时对象
}

// 高效方式
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
    sb.append(i);  // 只在内部数组扩容
}
String result = sb.toString();

1.7 输入输出(Scanner)

基本使用

import java.util.Scanner;

public class ScannerDemo {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 读取字符串
        System.out.print("请输入姓名:");
        String name = scanner.next();        // 读到空格/换行停止
        System.out.print("请输入年龄:");
        int age = scanner.nextInt();         // 读取整数
        System.out.print("请输入身高:");
        double height = scanner.nextDouble(); // 读取浮点数
        System.out.print("是否成年:");
        boolean adult = scanner.nextBoolean(); // 读取布尔值
        System.out.println("姓名:" + name + ",年龄:" + age);
    }
}

常用方法

方法说明
next()读取下一个单词(空格/换行分隔)
nextLine()读取整行(到换行为止)
nextInt()读取 int
nextDouble()读取 double
nextBoolean()读取 boolean
hasNext()是否有下一个标记
hasNextInt()下一个标记是否能转为 int
close()关闭 Scanner

缓冲区问题(重点)

Scanner scanner = new Scanner(System.in);

System.out.print("请输入年龄:");
int age = scanner.nextInt();      // 读取 25,但换行符 \n 留在缓冲区

// System.out.print("请输入姓名:");
// String name = scanner.nextLine();  // 直接读取了残留的 \n,返回空字符串!

// 解决方案:消耗掉残留的换行符
scanner.nextLine();               // 清除缓冲区的 \n

System.out.print("请输入姓名:");
String name = scanner.nextLine(); // 正常读取
System.out.println("年龄:" + age + ",姓名:" + name);

输入校验

import java.util.Scanner;
import java.util.InputMismatchException;

Scanner scanner = new Scanner(System.in);
int number = 0;
boolean valid = false;

while (!valid) {
    try {
        System.out.print("请输入一个整数:");
        number = scanner.nextInt();
        valid = true;
    } catch (InputMismatchException e) {
        System.out.println("输入无效,请重新输入!");
        scanner.next();  // 清除无效输入
    }
}
System.out.println("你输入的是:" + number);

最佳实践

// 1. 使用完毕后关闭(System.in 一般不关,但在文件/流场景必须关)
Scanner scanner = new Scanner(System.in);
// ... 操作 ...
scanner.close();

// 2. 格式化输出
String name = "张三";
int score = 95;
System.out.printf("姓名:%s,成绩:%d%n", name, score);
System.out.format("姓名:%-10s 成绩:%03d%n", name, score);

// 3. 提供清晰输入提示
System.out.println("=== 学生信息录入 ===");
System.out.print("姓名(字符串):");

格式化输出常用占位符

占位符说明示例
%s字符串printf("%s", "Hello")
%d十进制整数printf("%d", 100)
%f浮点数printf("%.2f", 3.1415)3.14
%c字符printf("%c", 'A')
%b布尔值printf("%b", true)
%n换行符(跨平台)
%x十六进制printf("%x", 255)ff

1.8 包管理

包(Package)概述

包用于组织 Java 类,防止命名冲突,提供访问保护。Java 使用包来模拟文件系统的目录结构。

package 语句

// 必须是 Java 文件的第一行非注释代码
package com.example.util;

// 一个 Java 文件只能有一个 package 语句
public class StringUtils {
    public static boolean isEmpty(String str) {
        return str == null || str.length() == 0;
    }
}

import 语句

// 位于 package 之后,类定义之前
package com.example.app;

import java.util.List;                   // 导入单个类
import java.util.ArrayList;              // 导入单个类
import java.util.*;                      // 导入整个包(不导入子包)
import static java.lang.Math.*;          // 静态导入

public class Demo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        // 静态导入后可直接使用方法
        double result = sqrt(pow(2, 3) + abs(-4));  // 不需要 Math. 前缀
        double pi = PI;
    }
}

静态导入详解

// 导入特定静态方法
import static java.lang.Math.max;
import static java.lang.Math.min;

// 导入所有静态成员
import static java.lang.Math.*;

int bigger = max(10, 20);    // 无需 Math.max()
int smaller = min(10, 20);   // 无需 Math.min()
double pi = PI;              // 无需 Math.PI
注意:过多使用静态导入会降低可读性,建议仅在频繁使用(如数学计算、测试断言)时使用。

目录结构对应关系

包名和目录结构必须严格对应:

项目根目录/
└── src/
    └── com/
        └── example/
            ├── util/
            │   ├── StringUtils.java     → package com.example.util;
            │   └── DateUtils.java       → package com.example.util;
            ├── model/
            │   └── User.java            → package com.example.model;
            └── app/
                └── Main.java            → package com.example.app;

包命名规范

规范示例
全小写字母com.example.myapp
域名倒序com.google.gson
避免关键字不要用 javajavax 开头
层级用点分隔com.company.project.module

Java 常用包一览(重点)

包名主要功能
java.lang核心类(自动导入):String、Math、System、Thread 等
java.util工具类:集合框架、日期、Scanner、Random 等
java.io输入输出:File、InputStream、Reader 等
java.net网络编程:Socket、URL、HttpURLConnection 等
java.sql数据库操作:Connection、ResultSet、Statement 等
java.math高精度数学:BigInteger、BigDecimal 等

附录:速查表

基本类型默认值与范围

类型默认值最小值最大值包装类
byte0-128127Byte
short0-3276832767Short
int0-2^312^31-1Integer
long0L-2^632^63-1Long
float0.0fFloat
double0.0dDouble
char'\u0000'065535Character
booleanfalseBoolean

数组 vs 集合

特性数组集合(ArrayList等)
长度固定动态可变
类型可存基本类型和对象只能存对象(自动装箱解决)
性能更高有扩容开销
API较少丰富(增删改查排序等)

本文档涵盖了 Java 基础语法的核心知识点:基本数据类型、变量与内存模型、运算符、类型转换、数组操作、字符串处理、Scanner 输入输出以及包管理机制。
1

评论

博主关闭了所有页面的评论