Java 基础-基础核心语法全通-一篇就够了

0 阅读26分钟

Java核心语法完整指南


前言:写给Java初学者的话

欢迎学习Java编程!如果你是第一次接触编程,不用担心,我会用最简单的方式带你入门。编程就像学习一门新语言,需要从基础开始,循序渐进。若你是已经有基础的人可以看看我在基础中踩过的坑

学习建议

  • 完全不是背出来的,理解概念很重要
  • 每个例子最好自己敲一遍,实操真的非常重要
  • 编程是实践技能,多写代码才能掌握

第一章:Java初体验 - 你的第一个程序

1.1 工具选择

个人推荐直接使用idea即可地址直接下载即可www.jetbrains.com/zh-cn/idea/…

1.2 什么是Java程序?

Java程序和其他语言一样就像一本说明书,告诉计算机要做什么。我们写的代码就是这份说明书。

1.3 第一个Java程序:Hello World

idea自带了java的全套工具,但是也是会检测你的Java环境的,关于java安装部分可以参考上一篇安装教程,这里不做赘述

在这里插入图片描述

点击新建项目,然后输入项目名称,然后最好是勾选添加示例代码

然后就会自动创建 在这里插入图片描述

我们先只看这个部分,去掉for的部分

/**
 * @author Anfioo  2026/04/04 22:47
 */
//TIP 要<b>运行</b>代码,请按 <shortcut actionId="Run"/> 或
// 点击装订区域中的 <icon src="AllIcons.Actions.Execute"/> 图标。
public class Main {
    public static void main(String[] args) {
        //TIP 当文本光标位于高亮显示的文本处时按 <shortcut actionId="ShowIntentionActions"/>
        // 查看 IntelliJ IDEA 建议如何修正。
        System.out.printf("Hello and welcome!");
    }
}

代码解释

  • public class HelloWorld:创建一个公共类,类名是HelloWorld
  • main方法:每个Java程序都必须有这个"大门",程序从这里开始
  • System.out.printf:在屏幕上打印文字
  • //和/**为注释
  • 其实当前无需理解为什么,只要知道这个可以打印一个文字即可,下面继续介绍

1.4 如何运行Java程序?

  1. 把代码保存为HelloWorld.java

  2. 打开命令行,输入:javac HelloWorld.java(编译)

  3. 再输入:java HelloWorld(运行)

  4. 看到"Hello, World!"就成功了!

  5. 这个是编译和运行,但是idea中只需要 在这里插入图片描述

    都可以运行 在这里插入图片描述

    成功输出

一、Java程序基础

1.1 第一个Java程序

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

1.2 注释

  • 单行注释// 这是单行注释
  • 多行注释/* 这是多行注释 */
  • 文档注释/** 这是文档注释 */
// 单行注释示例
public class CommentExample {
    /*
     * 多行注释示例
     * 可以写多行说明
     */
    public static void main(String[] args) {
        System.out.println("注释示例"); // 行尾注释
    }
}

1.3 关键字

Java中具有特殊含义的保留字,全部小写:

  • publicclassstaticvoidintifforwhile

    这些是不能设置变量之类的使用这个保留的关键字,会报错

1.4 标识符命名规则

  • 组成:字母、数字、$_
  • 规则:
    1. 不能以数字开头
    2. 不能是关键字
    3. 区分大小写
// 正确的标识符
int age;
String userName;
double $price;
int _count;

// 错误的标识符
int 123age;     // 数字开头
String class;   // 关键字

1.5 命名规范

  • 类名:大驼峰,如 StudentInfo
  • 方法名:小驼峰,如 getStudentName
  • 变量名:小驼峰,如 studentAge
  • 常量名:全大写,下划线分隔,如 MAX_VALUE
  • 包名:全小写,如 com.example.anfioo

二、变量与数据类型

2.1 变量声明与初始化

// 声明变量
int age;
String name;

// 初始化变量
age = 20;
name = "张三";

// 声明并初始化
double price = 99.99;
boolean isStudent = true;

2.2 基本数据类型

整数类型
byte b = 100;      // 1字节,范围:-128 ~ 127
short s = 1000;    // 2字节,范围:-32768 ~ 32767
int i = 100000;    // 4字节,范围:-2^31 ~ 2^31-1
long l = 100000L;  // 8字节,范围:-2^63 ~ 2^63-1
浮点类型
float f = 3.14f;   // 4字节,单精度
double d = 3.14159; // 8字节,双精度
字符类型
char c1 = 'A';     // 单个字符
char c2 = 65;      // ASCII码
char c3 = '\u0041'; // Unicode编码
布尔类型
boolean flag1 = true;
boolean flag2 = false;
数据类型关键字占用字节取值范围代码示例
整数类型byte1 字节-128 ~ 127byte b = 100;
整数类型short2 字节-32768 ~ 32767short s = 1000;
整数类型int4 字节-2³¹ ~ 2³¹-1int i = 100000;
整数类型long8 字节-2⁶³ ~ 2⁶³-1long l = 100000L;
浮点类型float4 字节单精度float f = 3.14f;
浮点类型double8 字节双精度double d = 3.14159;
字符类型char2 字节0 ~ 65535char c1 = 'A';
char c2 = 65;
char c3 = '\u0041';
布尔类型boolean1 字节true / falseboolean flag1 = true;
boolean flag2 = false;

2.3 引用数据类型

String str = "Hello Java";  // 字符串
int[] arr = new int[5];     // 数组

2.4 类型转换

自动类型转换(隐式转换)
int a = 100;
double b = a;  // int自动转换为double

byte x = 10;
int y = x;     // byte自动转换为int
强制类型转换(显式转换)
double d = 3.14;
int i = (int)d;  // 强制转换为int,结果为3

long l = 100L;
int j = (int)l;  // 强制转换为int

三、运算符

3.1 算术运算符

int a = 10, b = 3;
System.out.println(a + b);  // 13
System.out.println(a - b);  // 7
System.out.println(a * b);  // 30
System.out.println(a / b);  // 3(整数除法)
System.out.println(a % b);  // 1(取余)

3.2 自增自减运算符

int count = 5;

count++;      // count变成6(先使用后加1)
++count;      // count变成7(先加1后使用)

count--;      // count变成6
--count;      // count变成5

int y = 10;
int z = y++ + 5;  // z = 15, y = 11
int w = ++y + 5;  // w = 17, y = 12

++/-- 在前 → 先运算再使用;++/-- 在后 → 先使用再运算,这个要自己用下才理解

3.3 赋值运算符

int money = 100;

money += 50;   // 相当于 money = money + 50,现在money=150
money -= 30;   // 相当于 money = money - 30,现在money=120
money *= 2;    // 相当于 money = money * 2,现在money=240
money /= 4;    // 相当于 money = money / 4,现在money=60

3.4 比较运算符

int a = 10, b = 20;
System.out.println(a == b);  // false
System.out.println(a != b);  // true
System.out.println(a > b);   // false
System.out.println(a < b);   // true
System.out.println(a >= 10); // true
System.out.println(b <= 20); // true

3.5 逻辑运算符

boolean x = true, y = false;
System.out.println(x && y);  // false(逻辑与)
System.out.println(x || y);  // true(逻辑或)
System.out.println(!x);      // false(逻辑非)

// 短路与(&&)和短路或(||)
int a = 10;
if (a > 5 || a / 0 > 1) {  // 不会报错,因为短路
    System.out.println("短路或");
}

3.6 三元运算符

int score = 85;
String result = score >= 60 ? "及格" : "不及格";
System.out.println(result);  // 输出:及格

int max = (10 > 5) ? 10 : 5;  // max = 10

三元运算符的核心用处 可以简化 if-else 分支语句,用一行代码实现简单的二选一逻辑,省略 ifelse 等关键词,让代码更简洁紧凑。

对比示例: // 三元运算符写法(一行搞定) String result = score >= 60 ? "及格" : "不及格";

// 等价的 if-else 写法(多行代码) String result; if (score >= 60) { result = "及格"; } else { result = "不及格"; }


四、流程控制

流程控制用于按指定逻辑顺序执行代码,分为 顺序结构分支结构循环结构 三大类,配合跳转语句可灵活控制执行流程。

4.1 顺序结构

核心特点:代码从上到下、从左到右依次执行,是最基础的执行流程。

// 代码按顺序执行,先输出第一步,再第二步,最后第三步
System.out.println("第一步");
System.out.println("第二步");
System.out.println("第三步");

顺序结构是所有程序的基础,所有分支、循环内部的代码块,本质上也是按顺序执行的

4.2 分支结构

根据条件判断,选择执行不同的代码块,分为 if 系列和 switch 两种。

4.2.1 if 语句

适合复杂条件判断(范围、多条件组合),支持单分支、双分支、多分支。

int score = 85;

// 多分支 if-else if-else
if (score >= 90) {
    System.out.println("优秀");
} else if (score >= 80) {
    System.out.println("良好");
} else if (score >= 60) {
    System.out.println("及格");
} else {
    System.out.println("不及格");
}
  1. if 后的条件表达式必须返回 boolean 类型true/false)。
  2. 多分支判断时,条件是互斥的,一旦某个条件满足,后续条件不会再判断。
  3. 单个语句块的 {} 可以省略,但推荐始终加上,避免代码歧义。
4.2.2 switch 语句

适合固定值匹配(如枚举、常量),代码可读性比多分支 if 更高。

int day = 3;
switch (day) {
    case 1:
        System.out.println("星期一");
        break;  // 跳出 switch,避免穿透
    case 2:
        System.out.println("星期二");
        break;
    case 3:
        System.out.println("星期三");
        break;
    case 4:
        System.out.println("星期四");
        break;
    case 5:
        System.out.println("星期五");
        break;
    default:  // 所有 case 都不匹配时执行
        System.out.println("周末");
}
  1. case 穿透问题:如果省略 break,会从匹配的 case 开始,依次执行后续所有 case 的代码,直到遇到 breakswitch 结束。
  2. switch 支持的类型:byte/short/int/char 及其包装类、String(Java 7+)、枚举类型。
  3. default 位置不固定,推荐放在最后;即使所有 case 都匹配,default 也不会执行。

4.3 循环结构

重复执行一段代码,直到满足终止条件,分为 forwhiledo-while 三种。

4.3.1 for 循环

适合已知循环次数的场景,初始化、条件判断、步进操作集中在一行,结构清晰。

// 场景1:打印1-10
for (int i = 1; i <= 10; i++) {  // 初始化; 循环条件; 步进
    System.out.println(i);
}

// 场景2:计算1-100的和
int sum = 0;
for (int i = 1; i <= 100; i++) {
    sum += i;  // 等价于 sum = sum + i
}
System.out.println("1-100的和:" + sum);  // 输出 5050
  1. for 循环的三个表达式都可以省略:for(;;) 会变成死循环,需配合 break 跳出。
  2. 初始化的变量 i局部变量,仅在循环体内有效。
4.3.2 while 循环

适合未知循环次数的场景,先判断条件,再执行循环体。

// 场景1:打印1-5
int i = 1;  // 初始化循环变量
while (i <= 5) {  // 循环条件
    System.out.println(i);
    i++;  // 步进操作,避免死循环
}

// 场景2:计算5的阶乘(5! = 5×4×3×2×1)
int num = 5;
int factorial = 1;
while (num > 0) {
    factorial *= num;  // 等价于 factorial = factorial * num
    num--;
}
System.out.println("5的阶乘:" + factorial);  // 输出 120

若循环条件一开始就为 falsewhile 循环一次都不会执行;务必在循环体内修改循环变量,否则会陷入死循环。

4.3.3 do-while 循环

至少执行一次循环体,再判断条件,适合需要“先执行,后判断”的场景。

int count = 0;
do {
    System.out.println("执行次数:" + (count + 1));
    count++;
} while (count < 3);  // 循环条件

do-while 循环的末尾必须加分号 ;,这是语法规定,容易遗漏。

4.4 跳转语句

用于控制循环或方法的执行流程,包括 breakcontinuereturn

// 1. break:跳出当前所在的循环/switch
System.out.println("=== break 示例 ===");
for (int i = 1; i <= 10; i++) {
    if (i == 5) {
        break;  // 当i=5时,直接跳出for循环
    }
    System.out.println(i);  // 输出 1-4
}

// 2. continue:跳过本次循环,直接进入下一次循环判断
System.out.println("=== continue 示例 ===");
for (int i = 1; i <= 5; i++) {
    if (i == 3) {
        continue;  // 跳过i=3的情况,不执行后续输出
    }
    System.out.println(i);  // 输出 1,2,4,5
}

// 3. return:结束当前方法,无论后面还有多少代码都不会执行
public static void testReturn() {
    System.out.println("=== return 示例 ===");
    for (int i = 1; i <= 5; i++) {
        if (i == 3) {
            return;  // 直接结束testReturn方法
        }
        System.out.println(i);  // 输出 1,2
    }
    System.out.println("这行不会执行");  // 永远不会被执行
}

// 调用方法
testReturn();
  1. break 可以搭配标签跳出多层嵌套循环(如 outer: for(...) { ... break outer; })。
  2. continue 只能跳过当前循环,不能跳出循环;同样支持标签,跳过指定层级的循环。
  3. return 不仅能结束循环,还会直接结束整个方法,是三者中“威力最大”的跳转语句。

4.5 嵌套循环

一个循环体内包含另一个完整的循环,常用于多维数据遍历(如矩阵、九九乘法表)。

// 打印九九乘法表
for (int i = 1; i <= 9; i++) {  // 外层循环:控制行数
    for (int j = 1; j <= i; j++) {  // 内层循环:控制每行的列数
        System.out.print(j + "×" + i + "=" + (i * j) + "\t");  // \t 制表符,对齐格式
    }
    System.out.println();  // 换行,开始下一行
}
  1. 嵌套循环的执行顺序:外层循环执行1次,内层循环执行全部次数,再回到外层循环的下一次。
  2. 尽量减少嵌套层级(推荐不超过3层),否则会降低代码可读性和执行效率。
  3. 可以用 break + 标签 直接跳出外层循环,避免多层 break 的冗余判断。

五、方法(函数)

方法是完成特定功能的代码块,可以重复调用,让代码更简洁、复用性更强、便于维护。


5.1 方法定义与调用

概念

  • 方法:具有独立功能的代码段,可以被重复调用
  • 定义格式修饰符 返回值类型 方法名(参数列表) { 方法体; return; }
  • 调用方式:直接调用 / 赋值调用 / 输出调用
public class MethodExample {
    // 无参数无返回值的方法
    public static void sayHello() {
        System.out.println("Hello!");
    }
    
    // 有参数无返回值的方法
    public static void greet(String name) {
        System.out.println("你好," + name);
    }
    
    // 有参数有返回值的方法
    public static int add(int a, int b) {
        return a + b;
    }
    
    public static void main(String[] args) {
        sayHello();                    // 直接调用
        greet("张三");                 // 传递参数调用
        int result = add(10, 20);      // 赋值调用
        System.out.println("10+20=" + result);
        
        System.out.println(add(5, 7)); // 输出调用
    }
}
  1. void 表示无返回值,不需要写 return
  2. 有返回值的方法必须用 return 带回结果
  3. 方法必须被调用才会执行,不会自动运行
  4. 方法只能定义在类中,不能嵌套定义

5.2 方法重载

概念

同一个类中,方法名相同,但参数列表不同,这就是方法重载。

判定条件

  • 参数个数不同
  • 参数类型不同
  • 参数顺序不同 与返回值类型无关!
public class OverloadExample {
    // 方法1:两个int相加
    public static int add(int a, int b) {
        return a + b;
    }
    
    // 方法2:三个int相加(参数个数不同)
    public static int add(int a, int b, int c) {
        return a + b + c;
    }
    
    // 方法3:两个double相加(参数类型不同)
    public static double add(double a, double b) {
        return a + b;
    }
    
    public static void main(String[] args) {
        System.out.println(add(10, 20));        // 调用方法1
        System.out.println(add(10, 20, 30));    // 调用方法2
        System.out.println(add(10.5, 20.5));    // 调用方法3
    }
}
  1. 方法重载只看方法名和参数列表
  2. 返回值不同不算重载
  3. 好处:使用同一个方法名完成相似功能,降低记忆成本

5.3 递归方法

概念

方法自己调用自己,称为递归。 必须有出口(结束条件),否则会出现栈溢出错误。

public class RecursionExample {
    // 计算阶乘(递归实现)
    public static int factorial(int n) {
        if (n == 0 || n == 1) { // 递归出口
            return 1;
        }
        return n * factorial(n - 1);
    }
    
    // 计算斐波那契数列
    public static int fibonacci(int n) {
        if (n == 1 || n == 2) { // 递归出口
            return 1;
        }
        return fibonacci(n - 1) + fibonacci(n - 2);
    }
    
    public static void main(String[] args) {
        System.out.println("5的阶乘:" + factorial(5));
        System.out.println("第6个斐波那契数:" + fibonacci(6));
    }
}
  1. 递归必须有出口,否则会栈溢出
  2. 递归层级不宜过深,否则效率低、耗内存
  3. 适合:阶乘、斐波那契、树遍历、文件搜索等数学/分治问题

递归 = 自己调用自己 + 明确结束条件 公式:问题 = 子问题 + 出口

这个是很重要的算法会用到的地方

六、数组

数组就是一个装数据的容器,专门用来存 相同类型 的数据,比如存全班同学的成绩、存一组数字。 它的特点是:长度固定(一旦创建,不能变多或变少),通过位置访问(每个数据都有自己的编号)。


6.1 数组声明与初始化

简单说,就是 创建数组 + 存数据,有三种常用方式,根据需求选就行。

// 方式1:动态初始化 → 先指定能装多少个,后面再填数据
// 比如创建一个能装5个整数的数组,初始时里面全是0
int[] arr1 = new int[5];

// 方式2:静态初始化 → 直接把要存的数据写进去,不用指定长度
// 下面这个数组就装了5个数字,长度自动是5
int[] arr2 = {1, 2, 3, 4, 5};

// 方式3:先声明,后赋值 → 适合先定义数组,后面再确定存什么数据
int[] arr3;
arr3 = new int[]{10, 20, 30};  // 这里不用写长度

// 给数组赋值、取值
arr1[0] = 100;          // 给数组第1个位置存100(数组的位置从0开始算)
System.out.println(arr2[2]);  // 取数组第3个位置的值,输出 3
  1. 数组的位置编号从0开始,比如长度为5的数组,位置是 0、1、2、3、4,没有5!
  2. 动态初始化时,整数数组默认装0,字符串数组默认装 null(空)。
  3. 直接写 {...} 只能在创建数组时用,分开写必须加 new int[]

6.2 数组遍历

遍历就是把数组里的每个数据都看一遍、用一遍,两种简单方法,新手优先记第一种。

int[] numbers = {10, 20, 30, 40, 50};

// 方式1:普通for循环 → 能知道数据在哪个位置,还能修改数据
// length 就是数组的长度,直接用就行
for (int i = 0; i < numbers.length; i++) {
    System.out.println("第" + (i+1) + "个数据:" + numbers[i]);
}

// 方式2:增强for循环 → 代码更简单,适合只看数据、不修改的场景
for (int num : numbers) {
    System.out.println("数据值:" + num);
}
  1. numbers.length 是数组的“长度属性”,直接写就行,别写成 length()
  2. 增强for循环不用记位置,写起来快,但没法修改原数组的数字
  3. 想改数组里的数据,就用普通for循环。

6.3 数组常见操作

数组最常用的就是 找最值、求和、反转、找数据,都是新手必学的基础功能。

6.3.1 求最大值和最小值

核心思路:先假设第一个数是最大/最小的,然后挨个比,遇到更大/更小的就替换。

int[] scores = {85, 92, 78, 95, 88};
int max = scores[0];  // 先假设第一个数是最高分
int min = scores[0];  // 先假设第一个数是最低分

// 从第二个数开始比,省得重复比第一个
for (int i = 1; i < scores.length; i++) {
    if (scores[i] > max) {
        max = scores[i];  // 发现更高的,就更新最高分
    }
    if (scores[i] < min) {
        min = scores[i];  // 发现更低的,就更新最低分
    }
}
System.out.println("最高分:" + max);  // 输出 95
System.out.println("最低分:" + min);  // 输出 78

别一上来就写 int max = 0;!如果数组里全是负数(比如 -5, -10),0就不是最大值了。

6.3.2 数组求和与平均值

核心思路:先把所有数加起来,总和除以个数就是平均值(注意算平均值时要转成小数)。

int[] numbers = {10, 20, 30, 40, 50};
int sum = 0;  // 总和从0开始加

for (int num : numbers) {
    sum += num;  // 把每个数都加到总和里
}

// 算平均值时,要把sum转成小数,不然会舍去小数部分(比如 151/5 会算成30,不是30.2)
double average = (double) sum / numbers.length;
System.out.println("总和:" + sum);       // 输出 150
System.out.println("平均值:" + average);  // 输出 30.0

关键一步:(double) sum 是把整数转成小数,这样除法结果才是小数。

6.3.3 数组反转

核心思路:首尾交换!比如第1个和最后1个换,第2个和倒数第2个换,直到中间。

int[] arr = {1, 2, 3, 4, 5};
System.out.println("原数组:");
for (int num : arr) {
    System.out.print(num + " ");  // 输出 1 2 3 4 5
}

// 反转核心代码:i是开头位置,j是结尾位置
for (int i = 0, j = arr.length - 1; i < j; i++, j--) {
    int temp = arr[i];  // 临时存一下开头的数
    arr[i] = arr[j];    // 把结尾的数放到开头
    arr[j] = temp;      // 把临时存的数放到结尾
}

System.out.println("\n反转后:");
for (int num : arr) {
    System.out.print(num + " ");  // 输出 5 4 3 2 1
}

循环条件是 i < j,别写成 i <= j!不然中间的数会被换回去,等于没反转。

6.3.4 数组查找(找某个数在不在)

核心思路:挨个找,找到就说“在”,并告诉位置;找不到就说“不在”。

int[] arr = {10, 20, 30, 40, 50};
int target = 30;  // 要找的数
boolean found = false;  // 标记有没有找到

for (int i = 0; i < arr.length; i++) {
    if (arr[i] == target) {
        System.out.println("找到" + target + "啦,位置是:" + i);  // 输出位置2
        found = true;
        break;  // 找到就别找了,省时间
    }
}

if (!found) {
    System.out.println("没找到" + target);
}

找到后一定要写 break,不然程序会把整个数组都遍历完,没必要。


6.4 二维数组

二维数组就是“数组里套数组”,可以理解成一个表格,有行和列,比如存全班同学的各科成绩。

// 方式1:创建一个3行4列的表格,初始全是0
int[][] matrix = new int[3][4];

// 方式2:直接填数据,每行可以不一样长(比如第一行3个,第三行2个)
int[][] scores = {
    {85, 90, 78},    // 第一行:张三的语文、数学、英语成绩
    {92, 88, 95},    // 第二行:李四的三科成绩
    {76, 85}         // 第三行:王五的两科成绩
};

// 取值:先写行,再写列 → 比如取李四的英语成绩(第二行第三列)
System.out.println("李四的英语成绩:" + scores[1][2]);  // 输出95

// 遍历:用两层循环,外层遍历行,内层遍历列
for (int i = 0; i < scores.length; i++) {  // scores.length 是行数
    for (int j = 0; j < scores[i].length; j++) {  // scores[i].length 是第i行的列数
        System.out.print(scores[i][j] + "\t");  // \t 让表格对齐
    }
    System.out.println();  // 每行结束后换行
}
  1. 二维数组的位置是 数组名[行号][列号],行和列的编号都从0开始。
  2. 行数就是 数组名.length,某一行有多少列,就用 数组名[行号].length

6.5 数组常见异常(新手必避坑)

数组最容易踩两个坑,运行时会报错,记住怎么防就行!

int[] arr = {1, 2, 3};
int[] arr2 = null;  // 这个数组是空的,没装任何数据

// 坑1:索引越界 → 想访问的位置不存在
// System.out.println(arr[5]);  // 错误!arr只有3个数据,位置是0、1、2,没有5

// 坑2:空指针异常 → 数组是空的,却想拿它的长度或数据
// System.out.println(arr2.length);  // 错误!arr2是null,没有长度

// 避坑方法:先判断,再使用
if (arr != null && arr.length > 5) {  // 先看数组是不是空的,再看长度够不够
    System.out.println(arr[5]);
} else {
    System.out.println("数组是空的,或者长度不够");
}
  1. 索引越界:别访问超出数组长度的位置,循环时用 i < 数组名.length 当条件。
  2. 空指针异常:用数组之前,先判断它是不是 null

七、输入输出

输入输出(I/O)是程序和用户交互的核心,控制台输出是程序给用户展示信息,键盘输入是用户给程序传递数据。 这里会用到 java.util.Scanner 工具类,你可以把类想象成“工具包”方法就是包里的工具,导入类才能使用对应的工具实现输入功能。


7.1 控制台输出

三种常用输出方式,对应不同的使用场景,核心是 System.out 这个“输出工具”。

// 1. print:输出内容后不换行,光标停在当前行末尾
System.out.print("不换行输出");
System.out.print(" → 看,我和上面的内容在一行\n"); // \n 是换行符,手动换行

// 2. println:输出内容后自动换行,最常用
System.out.println("换行输出");
System.out.println("我在新的一行");

// 3. printf:格式化输出,按指定格式展示数据(比如保留小数位数)
// 格式说明符:%s 代表字符串,%d 代表整数,%.2f 代表保留2位小数的浮点数
System.out.printf("格式化输出:%s今年%d岁\n", "张三", 20);

// 格式化输出示例:控制小数位数
int age = 20;
double score = 95.5;
// %.2f 表示把score格式化为保留2位小数的浮点数,这里会输出 95.50
System.out.printf("年龄:%d,分数:%.2f\n", age, score);
  1. 日常打印信息优先用 println,自动换行更省心;
  2. 需要精准控制格式(比如保留小数、对齐文本)用 printf
  3. print 适合需要手动控制换行位置的场景。

7.2 键盘输入

想要读取用户从键盘输入的内容,必须用 Scanner 类——这个类就是专门的“输入工具包”。 你可以这样理解:

  • 类(Scanner) = 一个带各种“输入工具”的工具箱;
  • 方法(nextLine()、nextInt()) = 工具箱里的螺丝刀、扳手,各有各的用途(读字符串、读整数);
  • import 语句 = 打开工具箱的钥匙,没有钥匙就用不了里面的工具。
// 导入 Scanner 工具包 → 拿到打开工具箱的钥匙
// 这行必须写在代码最上面(类定义之前)
import java.util.Scanner;

public class InputExample {
    public static void main(String[] args) {
        // 创建 Scanner 对象 → 打开工具箱,准备用工具
        // System.in 表示“从键盘获取输入”
        Scanner scanner = new Scanner(System.in);
        
        System.out.print("请输入姓名:");
        // nextLine():读取一整行字符串(包括空格),适合读姓名
        String name = scanner.nextLine();
        
        System.out.print("请输入年龄:");
        // nextInt():读取整数,专门用来接收数字
        int age = scanner.nextInt();
        
        System.out.print("请输入身高(米):");
        // nextDouble():读取小数(双精度浮点数)
        double height = scanner.nextDouble();
        
        // 输出用户输入的信息,验证是否读取成功
        System.out.println("--- 输入信息 ---");
        System.out.println("姓名:" + name);
        System.out.println("年龄:" + age);
        System.out.println("身高:" + height + "米");
        
        // 关闭 Scanner → 用完工具箱要关上,释放资源
        scanner.close();
    }
}
  1. 工具和用途要匹配:读字符串用 nextLine(),读整数用 nextInt(),读小数用 nextDouble(),别混用;
  2. 注意 nextLine() 的坑:如果前面用了 nextInt()/nextDouble(),再用 nextLine() 会读取到“空行”,解决方法是多写一行 scanner.nextLine() 吸收换行符;
  3. 用完记得关:调用 scanner.close() 是好习惯,避免占用系统资源。
  1. 输入的数据类型要和方法匹配!比如用 nextInt() 时输入字母,程序会直接报错;
  2. import java.util.Scanner; 这行不能漏,漏了就会提示“找不到 Scanner 类”。

八、综合示例

这里的两个小案例,整合了数组、循环、分支、键盘录入、随机数等基础知识点,适合新手理解 Java 基础语法的实际应用。


8.1 学生成绩管理系统(简化版)

核心知识点:数组存储数据、for循环遍历、键盘录入Scanner、最值查找、平均值计算

import java.util.Scanner;  // 导入键盘录入工具类,这是基础IO知识点

// 学生成绩管理系统:实现录入姓名和成绩、计算平均分、找最高分最低分
public class StudentGradeSystem {
    public static void main(String[] args) {
        // 1. 创建Scanner对象,用于接收用户从控制台输入的数据
        Scanner scanner = new Scanner(System.in);
        
        // 提示用户输入学生人数,这是动态确定数组长度的关键
        System.out.print("请输入学生人数:");
        int studentCount = scanner.nextInt();
        
        // 2. 定义两个数组,分别存储学生姓名和对应的成绩
        // 数组长度由用户输入的人数决定,体现数组动态初始化的用法
        String[] names = new String[studentCount];  // 字符串数组存姓名
        int[] scores = new int[studentCount];       // int数组存成绩
        
        // 3. 用for循环遍历数组,逐个录入学生信息
        // 这里用到了普通for循环(带索引),因为需要给数组元素赋值
        for (int i = 0; i < studentCount; i++) {
            System.out.print("请输入第" + (i+1) + "个学生的姓名:");
            names[i] = scanner.next();  // 给姓名数组的第i个位置赋值
            
            System.out.print("请输入" + names[i] + "的成绩:");
            scores[i] = scanner.nextInt();  // 给成绩数组的第i个位置赋值
        }
        
        // 4. 计算所有学生的成绩总和,用于后续算平均分
        // 这里用到增强for循环,因为只需要读取成绩,不需要索引
        int total = 0;  // 总和初始化为0
        for (int score : scores) {
            total += score;  // 累加每个学生的成绩
        }
        // 计算平均分:强制转换为double,避免整数除法丢失小数
        double average = (double) total / studentCount;
        
        // 5. 查找最高分和最低分,以及对应的学生姓名
        // 初始化最值为数组第一个元素,避免出现0值错误
        int maxScore = scores[0];
        int minScore = scores[0];
        String maxName = names[0];
        String minName = names[0];
        
        // 从第二个元素开始遍历比较,节省一次循环
        for (int i = 1; i < studentCount; i++) {
            // 分支结构if:判断当前成绩是否大于最高分
            if (scores[i] > maxScore) {
                maxScore = scores[i];  // 更新最高分
                maxName = names[i];    // 更新最高分对应的姓名
            }
            // 分支结构if:判断当前成绩是否小于最低分
            if (scores[i] < minScore) {
                minScore = scores[i];  // 更新最低分
                minName = names[i];    // 更新最低分对应的姓名
            }
        }
        
        // 6. 输出统计结果,格式化打印信息
        System.out.println("\n=== 成绩统计结果 ===");
        System.out.println("平均分:" + average);
        System.out.println("最高分:" + maxName + " - " + maxScore + "分");
        System.out.println("最低分:" + minName + " - " + minScore + "分");
        
        // 关闭Scanner,释放资源,养成良好编程习惯
        scanner.close();
    }
}

8.2 猜数字游戏

核心知识点:随机数生成Randomdo-while循环(先执行后判断)、if-else分支、计数器

import java.util.Random;   // 导入随机数生成工具类
import java.util.Scanner;  // 导入键盘录入工具类

// 猜数字游戏:生成1-100的随机数,用户猜数字,给出大/小提示,直到猜对
public class GuessNumberGame {
    public static void main(String[] args) {
        // 1. 创建Random对象,用于生成随机数
        Random random = new Random();
        // 2. 创建Scanner对象,用于接收用户猜测的数字
        Scanner scanner = new Scanner(System.in);
        
        // 生成1-100的随机数:nextInt(100)生成0-99,+1后变成1-100
        int target = random.nextInt(100) + 1;
        int guess;  // 存储用户每次猜测的数字
        int attempts = 0;  // 计数器:记录用户猜的次数
        
        // 游戏欢迎语
        System.out.println("欢迎来到猜数字游戏!");
        System.out.println("我已经想好了一个1-100之间的数字,请开始猜吧!");
        
        // 3. 用do-while循环实现游戏逻辑:至少执行一次(先猜再判断)
        // 这是do-while循环的典型场景:需要先执行循环体,再判断条件
        do {
            System.out.print("请输入你的猜测:");
            guess = scanner.nextInt();  // 接收用户输入的猜测值
            attempts++;  // 每猜一次,计数器加1
            
            // 4. 用if-else if-else分支结构,根据猜测结果给出提示
            if (guess > target) {
                System.out.println("猜大了!");
            } else if (guess < target) {
                System.out.println("猜小了!");
            } else {
                // 猜对了,输出恭喜信息和猜测次数
                System.out.println("恭喜你,猜对了!");
                System.out.println("你一共猜了" + attempts + "次");
            }
        } while (guess != target);  // 循环条件:没猜对就继续猜
        
        // 关闭资源
        scanner.close();
    }
}

九、常见问题与练习

9.1 常见错误

  1. 忘记分号System.out.println("Hello")

  2. 大小写错误system.out.println

  3. 括号不匹配if (x > 5 {

  4. 数组越界:访问不存在的索引

  5. 空指针:使用未初始化的对象

    但是一般使用idea这些都是自动化的,并且有完美的提示 在这里插入图片描述

    鼠标移动到这个红色的部分

    在这里插入图片描述

    非常清晰的就是展示有什么错误


总结

本指南涵盖了Java基础语法的核心内容,适合初学者系统学习。建议按照以下顺序学习,可以结合ai进行学习:

  1. 基础语法:变量、数据类型、运算符
  2. 流程控制:条件判断、循环
  3. 方法:函数定义、调用、重载
  4. 数组:一维数组、二维数组
  5. 综合应用:结合所学知识解决实际问题

学习编程最重要的是实践,建议在学习每个知识点后都编写相应的代码进行练习。遇到问题时,可以查阅官方文档或在线资源,逐步培养解决问题的能力。

祝大家学习顺利,早日掌握Java编程!