深浅模式
Java 简介
Java 是什么? 简单来说,它是一门面向对象的编程语言,就像我们日常使用的语言一样,有自己的语法规则和表达方式。
作为面向对象语言,Java 有三大核心特性:
- 封装 - 把数据和操作数据的方法捆绑起来
- 继承 - 允许基于已有的类创建新类
- 多态 - 同一个操作作用于不同对象,产生不同结果
常说的 Java 三大版本是:
版本 | 描述 |
---|---|
Java SE (Standard Edition) 标准版 | 是基础款,用于开发普通桌面程序。日常学习 Java 主要接触这个版本。 |
Java EE (Enterprise Edition) 企业版 | 是升级版,增加了很多企业级功能,适合开发复杂的商业应用。 |
Java ME(Micro Edition) 微型版 | 是精简版,为资源有限的设备(如早期的手机)设计的。 |
开发工具
想写 Java 程序,你首先需要安装 JDK(Java Development Kit)。这就像是一个工具箱,里面装着开发 Java 程序所需的各种工具。
- JDK(Java Development Kit) - 开发工具包:包含了编写、编译和调试 Java 程序所需的所有工具,比如编译器、调试器等。
- JRE(Java Runtime Environment) - 运行环境:JDK 中已包含 JRE。如果你只想运行 Java 程序而不是开发,只需安装 JRE 就够了。JRE 包含 Java 虚拟机(JVM),就是实际运行 Java 程序的"发动机"。
简单理解:JDK 是给开发者用的,JRE 是给用户用的。作为学习者,我们需要安装 JDK。
在选择版本时,选择官方指定的长期支持版 LTS 版本(Long Term Support)
集成开发环境
集成开发环境(IDE)就像是一个高级的编辑器,它不仅可以让你编写代码,还能帮你分析代码、编译程序、调试问题,是开发 Java 程序的得力助手。
现在最受 Java 开发者欢迎的 IDE 非 Intellij IDEA 莫属了,这是 JetBrains 公司的明星产品。
IDEA 中有很多快捷键可以提高我们的开发效率,常见的有:
快捷键 | 功能说明 |
---|---|
CTRL + D | 复制一行 |
CTRL + Y | 删除当前行 |
CTRL + ALT + L | 格式化代码风格 |
ALT + SHIFT + ↑,ALT + SHIFT+ ↓ | 上下移动当前代码 |
CTRL + /,CTRL + SHIFT + / | 注释选中的代码 |
Java 程序结构
Java 程序就像一个有层次的组织结构,从小到大依次是:
- 方法(Method):这是 Java 程序的"原子",负责完成具体的功能。比如计算器上的"+"按钮背后,就对应着一个执行加法的方法。
- 类(Class):当多个相关的方法组合在一起时,就形成了一个"类"。比如计算器类里会包含加减乘除等多个方法。
- 包(Package):当项目变得复杂,类越来越多,我们就需要将相关的类放在一个文件夹里,这个文件夹在 Java 中叫"包"。
- 项目/工程(Project):最后,所有的包组合在一起,形成一个完整的应用程序,这就是一个"项目"。
每个 Java 程序都有一个"大门",这个大门就是 main 方法。当你运行程序时,Java 会先找到这个方法,然后从这里开始执行。
无论你写多复杂的程序,都需要有一个 main 方法作为起点,它的写法是固定的:
Java
public static void main(String[] args){
// 你的代码从这里开始执行
}
Java 程序运行原理
我们写的 Java 代码(.java 文件)对计算机来说其实是"天书",计算机只认识 0 和 1 组成的机器码。
Java 的解决方案很聪明:
- 先用"编译器"把.java 文件转换成.class 文件(字节码)
- 然后再由 Java 虚拟机(JVM)在运行时将这些字节码转换成机器码
这种工作方式让 Java 成为一种"编译型语言"。编译好的程序可以独立运行,不需要再次编译。
而且,由于有 JVM 这个"翻译官"的存在,同一个 Java 程序可以在不同的操作系统上运行,只要那里安装了 JVM 就行。这就是常说的"一次编写,到处运行"。
想体验一下原始的 Java 开发过程吗?打开命令行工具(CMD),在命令行工具中:
- 先把.java 文件编译成.class 文件
bash
javac 你的程序.java
- 然后运行编译好的程序
bash
java 你的程序
这就是最基础的 Java 程序编译和运行过程。当然,在实际开发中,我们通常会使用 IDE 来自动完成这些步骤。
注释
注释是程序员的"备忘录",它们不会被执行,只是帮助人类理解代码的说明文字。
写注释绝对是个好习惯!因为刚写完的代码只有你和上帝看得懂,过几天可能就只剩上帝能看懂了...
Java 提供了三种不同风格的注释:
- 单行注释 - 简短说明就用它
java
// 这是一行单行注释,适合简短的解释
- 多行注释 - 需要写一段话时用它
java
/*
这是多行注释,
可以随意换行,
适合较长的说明
*/
- 文档注释 - 正式场合的专业选择
java
/**
* 这是文档注释,不仅是注释
* 还能被工具自动提取生成API文档
* 一般用在类、方法和重要变量的说明上
*/
在 IDEA 中快速添加注释
不用手打那些符号,记住这两个快捷键就行:
Ctrl
+/
→ 快速添加/删除单行注释Ctrl
+Shift
+/
→ 快速添加/删除多行注释
生成文档注释
文档注释的强大之处在于可以用 javadoc 工具将它们转换成漂亮的 HTML 文档,这也是所有官方 Java API 文档的生成方式:
bash
javadoc -d 文件夹 -encoding 代码编码 程序名.java
-d 文件夹
:指定生成的文档放在哪个目录-encoding 代码编码
:指定源代码的编码方式(如 UTF-8)程序名.java
:要处理的 Java 源文件
例如,生成当前项目文档可以这样用:
bash
javadoc -d doc -encoding UTF-8 *.java
这个简单命令就能让你的注释变身为专业文档,是开源项目和团队协作的必备技能!
变量与常量
变量
变量就像是内存中的一个小盒子,你可以往里面放东西,也可以随时替换里面的内容。
Java
// 语法:数据类型 变量名 = 初始值;
int score = 95; // 声明了一个整数变量,初始值是95
score = 98; // 可以随时修改它的值
为什么 Java 要求我们声明变量类型?因为 Java 是一种强类型语言,它需要预先知道这个"盒子"有多大,才能准确分配内存空间。不同类型的数据占用的空间是不同的。
常量
常量也是内存中的一块空间,但它的特点是一旦赋值就不能再改变。
Java
// 语法:final 数据类型 常量名 = 值;
final double PI = 3.14159265; // 定义一个圆周率常量
// PI = 3.14; // 错误!常量不能被修改
常量名通常全部大写,多个单词用下划线连接,这是一种编程约定,让人一眼就能认出它是常量。
标识符
标识符就是你自己创造的名字,用来命名变量、方法、类等各种东西的字符串。
标识符的组成很简单:字母、数字、下划线_或美元符号$。
不过有个小限制:不能以数字开头,必须以字母、下划线或美元符号打头。
还有,你不能用 Java 已经"预定"的词(关键字或保留字)作标识符。
- 关键字: Java 已经赋予特殊含义的词,比如 if、else、class 等,这些词是 Java 的"保留地",不能用来命名你自己的东西。
- 保留字: 现在 Java 还没用上,但未来可能会用的词。也不建议你拿来用。
命名规范
编程世界有一套大家都认可的命名习惯,遵循这些习惯会让你的代码更加专业:
- 包名:全小写,用点隔开,比如
java.util
- 类名/接口名:每个单词首字母大写(大驼峰),如
StudentInfo
- 方法名/变量名:首单词小写,后面单词首字母大写(小驼峰),如
getUserName
- 常量名:全大写,单词间用下划线,如
MAX_VALUE
数据类型
基本数据类型
Java 的基本数据类型就像不同形状的积木,各有各的用途:
- 整数类型:用来存储整数值
类型 | 存储大小 | 能装多少数字 | 适用场景 |
---|---|---|---|
byte | 1 个字节 | -128 到 127 | 节省空间的小整数 |
short | 2 个字节 | 约 ±3.2 万 | 较小范围的整数 |
int | 4 个字节 | 约 ±21 亿 | 最常用,默认整数类型 |
long | 8 个字节 | 非常大的范围 | 超大整数时使用 |
默认整数是 int 类型。如果要用 long 类型,需要在数字后加上字母 L
例如:long bigNumber = 123456789L;
基本类型之间的计算会自动进行类型转换,规则是"小转大",不会丢失精度。例如 byte + int 的结果是 int 类型。
特别注意:byte、short、char 三种类型的数据在计算时都会先转成 int 类型。
- 浮点类型:用来存储带小数点的数值
类型 | 存储大小 | 精度 | 适用场景 |
---|---|---|---|
float | 4 个字节 | 约 7 位有效数字 | 对精度要求不高的情况 |
double | 8 个字节 | 约 15 位有效数字 | 默认浮点类型,精度更高 |
默认小数是 double 类型。如果要用 float 类型,需要在数字后加上字母 F
例如:float price = 19.99F;
- 布尔类型:只存储 true 或 false 两种状态
类型 | 存储大小 | 取值 | 适用场景 |
---|---|---|---|
boolean | 1 个字节 | true/false | 条件判断,逻辑控制 |
- 字符类型:存储单个字符
类型 | 存储大小 | 取值范围 | 适用场景 |
---|---|---|---|
char | 2 个字节 | 0 到 65535(所有 Unicode 字符) | 存储单个字符 |
字符值需要用单引号括起来
如:char grade = 'A';
引用数据类型
除了上面这些基本类型外,Java 中的其他类型都是引用数据类型。
最常见的就是 String(字符串)。
- String 类:用来存储文本
java
String name = "张三"; // 字符串用双引号
虽然 String 看起来很基础,但它其实不是基本类型,而是一个类。不过 Java 对它有特殊处理,让它用起来像基本类型一样简单。
从键盘录入
想让你的程序接收用户输入的数据?Java 提供了一个很方便的工具——Scanner 类。使用它只需要三步走:
第一步:告诉 Java 你要用 Scanner
就像借用工具前要先说一声一样,使用 Scanner 前需要先"导入"它:
Java
import java.util.Scanner; // 在程序开头加上这一行
不用担心记不住这行代码,现代 IDE(如 IDEA)会在你需要使用 Scanner 时自动添加这行导入语句。
第二步:创建一个 Scanner"工具"
导入后,还需要创建一个 Scanner 对象才能使用它:
Java
Scanner scanner = new Scanner(System.in);
这行代码的意思是:创建一个名为 scanner 的扫描器,它会从 System.in(也就是键盘)获取输入。
这个 scanner 就像是你和键盘之间的"翻译官",负责把用户敲击键盘的内容转换成 Java 程序能理解的数据。
第三步:使用 Scanner 获取不同类型的输入
Scanner 提供了多种方法来读取不同类型的数据:
java
// 读取整数
int age = scanner.nextInt();
System.out.println("你的年龄是:" + age);
// 读取小数
double height = scanner.nextDouble();
System.out.println("你的身高是:" + height + "米");
// 读取字符串(整行)
scanner.nextLine(); // 注意:用来清除之前输入的回车符
String name = scanner.nextLine();
System.out.println("你的名字是:" + name);
// 读取单个词
String word = scanner.next();
System.out.println("你输入的单词是:" + word);
如果你想读取字符(char 类型),Scanner 没有直接提供 nextChar()方法,但你可以这样做:
java
char gender = scanner.next().charAt(0); // 读取输入的第一个字符
不过在实际开发中,我们通常直接用 String 类型代替单个 char,使用起来更方便。
⚠️ 注意事项:
当你混用nextInt()
/nextDouble()
和nextLine()
时,可能会出现nextLine()
直接被跳过的情况。这是因为前面的方法只读取值而不读取回车符,而 nextLine()会读取这个遗留的回车符。解决方法是在它们之间加一个额外的 scanner.nextLine()来"吃掉"这个回车符。
运算符
算术运算符
这些是我们最常用的运算符,就像计算器上的按钮:
类型 | 运算符 | 描述 |
---|---|---|
加减乘除 | + - * / | 基本的四则运算符 |
取模 | % | 两数相除的的余数, 舍去整数部分. |
注意: 整数相除的结果还是整数,小数部分会被直接舍去!
例如 5/2 得到的是 2 而不是 2.5。
如果你需要得到小数结果,至少有一个操作数必须是小数,比如 5.0/2 或 5/2.0。
数字拆分
在实际编程中,我们经常需要将一个多位数拆分成单个数位进行处理。这个看似简单的操作是运算符(特别是%
和/
)的绝佳应用场景。
基本原理:
- 使用
%
(取模)获取个位数 - 使用
/
(整除)去掉已处理的数位
java
// 将一个三位数拆分为个位、十位和百位
int number = 745;
int ones = number % 10; // 获取个位:5
int tens = number / 10 % 10; // 获取十位:4
int hundreds = number / 100; // 获取百位:7
System.out.println("个位是:" + ones);
System.out.println("十位是:" + tens);
System.out.println("百位是:" + hundreds);
拆分过程解析:
number % 10
→745 % 10 = 5
(余数就是个位数)number / 10
→745 / 10 = 74
(整除 10 后,十位变成了个位)74 % 10 = 4
(现在可以用同样的方法获取十位)number / 100
→745 / 100 = 7
(直接得到百位)
进阶:循环提取所有数位
java
int number = 9527;
System.out.println("从右到左依次是:");
while (number > 0) {
System.out.print(number % 10 + " "); // 输出当前个位
number /= 10; // 去掉已处理的个位
}
// 输出:7 2 5 9
这个技巧在很多算法题中都能派上用场,比如判断回文数、计算数字和、翻转整数等,绝对是你的编程武器库中的必备技能!
自增自减
除了基本运算,还有两个特殊的操作符:
运算符 | 名称 | 效果 |
---|---|---|
++ | 自增 | 变量值加 1 |
-- | 自减 | 变量值减 1 |
自增自减有两种用法,放在变量前和放在变量后的效果不同:
java
int a = 5;
int b = ++a; // 先加后赋值,a变成6,b也是6
int c = 5;
int d = c++; // 先赋值后加,d是5,而c变成6
这就像两种不同的工作风格:
- 前置++:先做事(加 1),再汇报结果(赋值)
- 后置++:先汇报当前状态(赋值),再做事(加 1)
赋值运算符
赋值运算符就是把右边的值存入左边的变量:
类型 | 运算符 | 描述 |
---|---|---|
赋值 | = | 简单的赋值运算符 |
四则赋值(包括取余) | *= , /= , %= , += , -= | 先计算右操作数, 再赋值 |
这些组合赋值运算符既省代码又能提高效率,就像"一键操作"。
关系运算符
关系运算符用来比较两个值之间的关系,结果永远是布尔值(true 或 false):
类型 | 运算符 | 描述 |
---|---|---|
等于 | == | 判断两边是否相等 |
不等于 | != | 判断两边是否不等 |
大于 小于 | > < | 判断左边是否大于右边 判断左边是否小于右边 |
大于等于 小于等于 | >= <= | 判断左边是否大于等于右边 判断左边是否小于等于右边 |
关系运算符只能直接比较基本数据类型!不能用==
直接比较字符串等引用类型是否相等。
比如:"hello" == "hello"
这样比较字符串是错误的做法!
正确的字符串比较方式是使用.equals()
方法:"hello".equals("hello")
逻辑运算符
当你需要组合多个条件时,逻辑运算符就派上用场了:
类型 | 运算符 | 描述 |
---|---|---|
逻辑与 | & | 两边都为 true, 结果为 true |
逻辑或 | | | 两边有一个为 true, 结果为 true |
逻辑非 | ! | 取反, 若操作数为 true, 结果为 false, 若操作数为 false, 结果为 true |
逻辑异或 | ^ | 两边结果相同 (都为 true 或都为 false), 结果为 true |
普通逻辑运算符有个问题:即使已经能确定最终结果,也会继续计算右边的表达式。这有时会造成不必要的计算甚至错误。
看这样一个例子:
java
// 判断一个人是否成年且有驾照
int age = 16;
boolean hasLicense = checkLicense(); // 假设这是个检查驾照的方法
// 使用普通逻辑与
boolean canDrive = age >= 18 & hasLicense; // 即使年龄不够,也会检查驾照
类型 | 运算符 | 描述 |
---|---|---|
短路与 | && | 如果左边为 false,直接返回 false,不再计算右边 |
短路或 | || | 如果左边为 true,直接返回 true,不再计算右边 |
在实际开发中,我们几乎总是使用短路运算符(&&和||),而不是&和|,因为它们既提高效率又能避免一些潜在错误。
位运算符(了解即可)
位运算符直接对整数的二进制位进行操作,在底层编程和特定算法中很有用:
运算符 | 名称 | 功能 |
---|---|---|
& | 按位与 | 对应位都为 1,结果才为 1 |
| | 按位或 | 对应位有一个为 1,结果就为 1 |
^ | 按位异或 | 对应位不同时为 1 |
~ | 按位取反 | 0 变 1,1 变 0 |
<< | 左移 | 各二进制位左移,右边补 0 |
>> | 右移 | 各二进制位右移,左边补符号位 |
>>> | 无符号右移 | 各二进制位右移,左边补 0 |
类型转换
在 Java 中,不同类型的数据有时需要相互转换。这有两种方式:自动转换和强制转换。
自动类型转换
当把"小容量"的数据类型赋值给"大容量"的变量时,Java 会自动完成转换:
Java
byte byteValue = 10; // 占1个字节
int intValue = byteValue; // 自动转成int(占4个字节)
自动转换遵循以下规则,从小到大依次是:
Java
byte → short → int → long → float → double
↗
char
虽然 float(4 字节)占用空间比 long(8 字节)小,但 float 表示的数值范围比 long 大,所以 long 可以自动转换为 float。
强制类型转换
当需要把"大容量"的数据类型转换成"小容量"的数据类型时,需要使用强制类型转换,因为这可能会损失精度:
Java
double doubleValue = 3.14;
int intValue = (int) doubleValue; // 强制转换,结果是3(小数部分被截断)
强制类型转换的语法是:在要转换的值前加上目标类型的括号(类型)。
强制类型转换可能导致数据丢失或失真:
- 浮点转整数:小数部分会被截断
- 大整数转小整数:高位部分会被截断
例如:byte b = (byte)130; 结果不是 130,而是-126(因为 byte 的范围是-128 到 127)
赋值运算中的隐式转换
在某些复合赋值运算符中(如+=、-=等),Java 会自动进行类型转换:
java
byte b = 10;
b += 5; // 等价于 b = (byte)(b + 5)
这种情况下,Java 编译器会自动插入强制类型转换,使结果符合左边变量的类型。
控制语句
条件判断
if-else
条件判断是程序的"大脑",让程序能够根据不同情况做出不同的决策:
Java
if (条件) {
// 如果条件为true,执行这里的代码
} else if (另一个条件) {
// 如果上面的条件为false,而这个条件为true,执行这里
} else {
// 如果以上所有条件都为false,执行这里
}
当条件下只有一行代码时,可以省略大括号,但为了代码清晰,建议保留:
java
if (score > 90) System.out.println("优秀"); // 可行,但不推荐
三目运算符
当你只需要根据条件选择两个值中的一个时,可以用更简洁的三目运算符:
Java
结果变量 = (条件) ? 值1 : 值2;
这相当于一个简化版的 if-else,条件为 true 时取值 1,为 false 时取值 2:
Java
// 使用if-else
String result;
if (score >= 60) {
result = "及格";
} else {
result = "不及格";
}
// 使用三目运算符,一行解决
String result = score >= 60 ? "及格" : "不及格";
switch-case
当需要根据一个变量的多个可能值做不同处理时,switch 比一堆 if-else 更清晰高效:
Java
switch (变量或表达式) {
case 值1:
// 当变量等于值1时执行
break; // 别忘了break,否则会继续执行下面的代码
case 值2:
// 当变量等于值2时执行
break;
// ...可以有更多case
default:
// 当变量不匹配任何case时执行
}
比如根据星期几决定做什么:
Java
int day = 3;
switch (day) {
case 1:
System.out.println("周一:开始新的一周");
break;
case 2:
case 3:
case 4:
case 5:
System.out.println("工作日:努力工作");
break;
case 6:
case 7:
System.out.println("周末:好好休息");
break;
default:
System.out.println("无效的日期");
}
Java 新版本(JDK 12+)提供了更简洁的 switch 语法:
Java
switch (day) {
case 1 -> System.out.println("周一:开始新的一周");
case 2, 3, 4, 5 -> System.out.println("工作日:努力工作");
case 6, 7 -> System.out.println("周末:好好休息");
default -> System.out.println("无效的日期");
}
从 JDK 17 开始,switch 甚至可以直接返回值:
Java
String plan = switch (day) {
case 1 -> "周一:开会日";
case 2, 3 -> "学习日";
case 4, 5 -> "编码日";
case 6, 7 -> "休息日";
default -> "错误的日期";
};
循环结构
循环让程序能够重复执行某些代码。Java 提供了几种循环结构:
for 循环
Java
for (初始化; 条件; 迭代) {
// 循环体,重复执行的代码
}
- 初始化:循环开始前执行一次
- 条件:每次循环前检查,为 true 才继续
- 迭代:每次循环后执行
java
// 打印1到5的数字
for (int i = 1; i <= 5; i++) {
System.out.println(i);
}
while 循环
当不知道需要重复多少次,只知道满足什么条件才停止时,用 while 循环:
java
while (条件) {
// 循环体
}
只要条件为 true,就会一直执行循环体:
java
// 从10倒数到1
int count = 10;
while (count > 0) {
System.out.println(count);
count--;
}
do-while 循环
这种循环保证至少执行一次循环体,然后再判断条件:
java
do {
// 循环体
} while (条件);
例如,实现一个简单的菜单:
java
int choice;
do {
System.out.println("1. 开始游戏");
System.out.println("2. 设置");
System.out.println("0. 退出");
System.out.print("请选择:");
choice = scanner.nextInt();
// 处理用户选择...
} while (choice != 0); // 当用户选择0时退出循环
打破循环常规
有时我们需要改变循环的正常流程:
break
- 直接"跳出"整个循环javafor (int i = 1; i <= 10; i++) { if (i == 5) { break; // 当i等于5时,跳出循环 } System.out.println(i); // 只会打印1、2、3、4 }
continue
- "跳过"本次循环剩余部分javafor (int i = 1; i <= 5; i++) { if (i == 3) { continue; // 当i等于3时,跳过本次循环剩余部分 } System.out.println(i); // 会打印1、2、4、5(没有3) }
可以给循环加上标签,然后通过break 标签名
或continue 标签名
控制外层循环:
java
outerLoop: for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
if (i * j > 4) {
break outerLoop; // 跳出最外层循环
}
System.out.println(i + " * " + j + " = " + (i * j));
}
}
方法
方法是 Java 程序的基本构建块,就像是一个个可以重复使用的"功能积木"。每个方法负责实现一个特定的功能,我们可以随时调用它们来完成任务。
如果没有方法:你每次想计算两个数的和,都要重复写同样的代码。
有了方法,你只需写一次,然后在需要的地方"呼叫"它就行了。方法让你的代码:
- 更有条理(代码分门别类)
- 可重复使用(写一次,用多次)
- 易于维护(修改一处,处处生效)
方法的基本结构
java
返回类型 方法名(参数类型 参数名, ...) {
// 方法体:实际执行的代码
return 返回值; // 如果有返回值的话
}
来看两个例子:
java
// 有返回值的方法 - 计算两数之和
int sum(int a, int b) {
return a + b; // 返回计算结果
}
// 无返回值的方法 - 只执行操作,不返回结果
void printGreeting() {
System.out.println("你好,欢迎学习Java!");
// 无需return语句(或者可以写return;)
}
调用方法
方法定义好后,需要调用才能发挥作用:
java
public static void main(String[] args) {
// 调用有返回值的方法,可以接收其结果
int result = sum(10, 20);
System.out.println("10 + 20 = " + result);
// 调用无返回值方法
printGreeting();
}
方法的参数
方法可以接收不同类型和数量的参数:
java
// 无参方法
void sayHello() {
System.out.println("Hello!");
}
// 单参数方法
void sayHelloTo(String name) {
System.out.println("Hello, " + name + "!");
}
// 多参数方法
double calculateRectangleArea(double length, double width) {
return length * width;
}
方法重载 - 同名不同参
Java 允许多个方法使用相同的名称,只要它们的参数列表不同(参数类型、数量或顺序)。这叫做"方法重载":
java
// 计算两个整数的和
int add(int a, int b) {
return a + b;
}
// 计算三个整数的和(参数数量不同)
int add(int a, int b, int c) {
return a + b + c;
}
// 计算两个浮点数的和(参数类型不同)
double add(double a, double b) {
return a + b;
}
在 IDEA 中,选中一段代码后按Ctrl
+ Alt
+ M
可以快速将这段代码提取为一个方法。这对重构代码特别有用!
全选代码后,按Ctrl
+ Shift
+ U
可以快速将选中内容转换为大写。
数组
数组是一种存储多个相同类型元素的容器,可以把它想象成一排连续的"格子",每个格子都可以存放一个值。
创建数组
有几种常见的方式可以创建数组:
java
// 方式1:先声明,后分配空间
int[] numbers; // 声明一个整数数组
numbers = new int[5]; // 分配有5个格子的空间
// 方式2:声明并分配空间
int[] scores = new int[3]; // 创建包含3个整数的数组
// 方式3:声明并初始化(直接赋值)
int[] ages = {25, 30, 18, 42}; // 创建并赋值
访问数组元素
数组中的每个元素都有一个索引(从 0 开始计数),通过索引可以访问或修改元素:
java
int[] marks = {85, 90, 75, 95, 60};
// 读取元素
System.out.println("第一个成绩是:" + marks[0]); // 输出85
System.out.println("最后一个成绩是:" + marks[4]); // 输出60
// 修改元素
marks[2] = 80; // 将第三个成绩从75改为80
⚠️ 警告:访问超出范围的索引会导致
ArrayIndexOutOfBoundsException
异常!
比如,对于长度为 5 的数组,尝试访问marks[5]
或marks[-1]
都会报错。
数组遍历
遍历数组就是按顺序访问数组中的每个元素。有几种常见方式:
传统 for 循环
java
int[] numbers = {10, 20, 30, 40, 50};
// 使用索引遍历
for (int i = 0; i < numbers.length; i++) {
System.out.println("第" + (i+1) + "个数是:" + numbers[i]);
}
增强 for 循环(for-each)
更简洁,但不能获取索引:
java
int[] numbers = {10, 20, 30, 40, 50};
// 直接获取每个元素
for (int num : numbers) {
System.out.println("数值:" + num);
}
二维数组
二维数组就像一个表格,有行和列:
java
// 创建3行2列的二维数组
int[][] matrix = {
{1, 2},
{3, 4},
{5, 6}
};
// 访问元素 [行][列]
System.out.println(matrix[0][0]); // 输出1(第1行第1列)
System.out.println(matrix[2][1]); // 输出6(第3行第2列)
// 遍历二维数组
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println(); // 换行
}
可变参数
Java 提供了一种特殊语法,让方法能接收不确定数量的参数:
java
// 计算任意数量整数的和
int sum(int... numbers) {
int total = 0;
for (int num : numbers) {
total += num;
}
return total;
}
// 调用方法
int result1 = sum(10, 20); // 传入2个参数
int result2 = sum(5, 10, 15, 20, 25); // 传入5个参数
int result3 = sum(); // 不传参数也行
可变参数实际上是作为数组处理的。有两点需要注意:
- 一个方法只能有一个可变参数
- 可变参数必须是方法的最后一个参数
java
// 正确:可变参数在最后
void printInfo(String name, int... scores) { }
// 错误:可变参数不在最后
void wrongMethod(int... numbers, String text) { } // 编译错误
数组的长度是固定的,创建后不能改变大小。如果需要动态调整大小的集合,可以使用 Java 集合框架中的 ArrayList、LinkedList 等类。
Java
// 声明方法
int sum(int a, int b){
return a + b;
}
void cleanMemory(){
System.out.println(sum);
}
public static voud main(String[] args){
// 调用有返回值的方法
int sum = sum(10, 20);
// 调用无返回值方法
clearMemory();
}
评论