Java编程:数组、对象与命令行参数的运用
1. 文件操作与 PrintStream 构造函数
在 Java 编程中,文件操作是常见的任务。
PrintStream
构造函数在处理文件时表现出特定的行为。如果找不到
GuestList.txt
文件,它会创建一个新文件并准备写入数据;若文件已存在,它会覆盖现有文件,重新创建一个空文件用于写入。所以,若不想文件被覆盖,在调用
PrintStream
构造函数前需做好预防措施。
在读取文件时,若要从
Employees.txt
文件读取数据,需使用
new Scanner(new File("Employees.txt"))
。若误写成
new Scanner("Employees.txt")
,将无法连接到文件。而在写入文件时,使用
new PrintStream("GuestList.txt")
即可,若错误地加入
new File
,Java 编译器会报错。
2. 数组条件表达式的注意事项
在某些代码中,条件表达式
roomNum < 10 && guests[roomNum] != 0
需谨慎使用。若将其改为
guests[roomNum] != 0 && roomNum < 10
,可能会引发问题。
3. 面向对象编程:Room 类
3.1 Room 类的定义
为了更好地管理酒店房间信息,引入了
Room
类。一个
Room
实例包含三个属性:房间内的客人数量、房间费率以及是否允许吸烟的标记。以下是
Room
类的代码:
import static java.lang.System.out;
import java.util.Scanner;
import java.text.NumberFormat;
public class Room {
private int guests;
private double rate;
private boolean smoking;
private static NumberFormat currency =
NumberFormat.getCurrencyInstance();
public void readRoom(Scanner diskScanner) {
guests = diskScanner.nextInt();
rate = diskScanner.nextDouble();
smoking = diskScanner.nextBoolean();
}
public void writeRoom() {
out.print(guests);
out.print("\t");
out.print(currency.format(rate));
out.print("\t");
out.println(smoking ? "yes" : "no");
}
}
3.2 Room 类的特点
-
属性
:
guests存储客人数量,rate存储房间费率,smoking是布尔类型,用于标记是否允许吸烟。 -
静态字段
:
currency是静态字段,使用NumberFormat.getCurrencyInstance()方法将房间费率格式化为货币形式。 -
方法
:
readRoom方法从文件中读取数据到对象的属性中;writeRoom方法将对象的属性信息输出。
4. 使用 Room 类创建房间数组
4.1 创建房间数组的代码
要创建一个房间数组,可使用以下代码:
import static java.lang.System.out;
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
class ShowRooms {
public static void main(String args[])
throws IOException {
Room rooms[];
rooms = new Room[10];
Scanner diskScanner =
new Scanner(new File("RoomList.txt"));
for (int roomNum = 0; roomNum < 10; roomNum++) {
rooms[roomNum] = new Room();
rooms[roomNum].readRoom(diskScanner);
}
out.println("Room\tGuests\tRate\tSmoking?");
for (int roomNum = 0; roomNum < 10; roomNum++) {
out.print(roomNum);
out.print("\t");
rooms[roomNum].writeRoom();
}
}
}
4.2 创建对象数组的步骤
创建对象数组与创建基本类型数组有所不同,需完成三个步骤:
1.
声明数组变量
:
Room rooms[];
声明一个
rooms
变量,用于引用数组。
2.
创建数组
:
rooms = new Room[10];
为数组分配内存空间,包含 10 个元素。
3.
构造每个对象
:在循环中使用
rooms[roomNum] = new Room();
为每个数组元素创建一个
Room
对象。
同时,还需为每个对象的属性赋值,可通过
readRoom
方法从文件中读取数据。以下是创建对象数组的步骤流程图:
graph TD;
A[声明数组变量] --> B[创建数组];
B --> C[构造每个对象];
C --> D[填充对象属性];
4.3 简化创建步骤
可以将前两个步骤合并,如
Room rooms[] = new Room[10];
,也可使用数组初始化器。
5. 数字格式化
在 Java 中,有多种方式可使数字显示更美观。例如,
Listing 7 - 7
使用
printf
,
Listing 10 - 1
使用
DecimalFormat
。而在
Room
类中,使用
NumberFormat
类的
getCurrencyInstance
方法来显示货币金额。
5.1 与其他格式化方式的比较
| 格式化方式 | 使用的类 | 创建方式 | 特点 |
|---|---|---|---|
Listing 10 - 1
|
DecimalFormat
| 构造函数 | 更具体的小数格式化 |
Room
类
|
NumberFormat
|
getCurrencyInstance
方法
| 方便创建货币格式 |
getCurrencyInstance
方法是工厂方法的一个例子,它能方便地创建常用对象,无需手动编写复杂的格式代码。
6. 条件运算符
在
Room
类的
writeRoom
方法中,使用了条件运算符
smoking ? "yes" : "no"
。条件运算符接受三个表达式,根据条件的真假返回其中一个表达式的值,类似于一个小型的
if
语句。
7. 命令行参数
7.1 命令行参数的概念
在早期,大多数程序员使用基于文本的开发界面。运行程序时,可在命令行输入额外信息,这些信息被称为命令行参数。例如,运行
MakeRandomNumsFile
程序时,可输入
java MakeRandomNumsFile MyNumberedFile.txt 5
,程序会读取这两个额外信息并使用它们。
7.2 Java 程序中使用命令行参数
在 Java 程序的
main
方法中,
String args[]
用于接收命令行参数。以下是使用命令行参数的代码示例:
import java.util.Random;
import java.io.PrintStream;
import java.io.IOException;
class MakeRandomNumsFile {
public static void main(String args[])
throws IOException {
Random generator = new Random();
if (args.length < 2) {
System.out.println
("Usage: MakeRandomNumsFile filename number");
System.exit(1);
}
PrintStream printOut = new PrintStream(args[0]);
int numLines = Integer.parseInt(args[1]);
for (int count = 1; count <= numLines; count++) {
printOut.println(generator.nextInt(10) + 1);
}
}
}
7.3 命令行参数的处理步骤
-
检查参数数量
:通过
args.length检查命令行参数的数量是否符合要求。 -
获取参数值
:
args[0]是文件名,args[1]是生成随机数的行数。 -
转换参数类型
:由于命令行参数是字符串类型,需使用
Integer.parseInt方法将其转换为整数类型。
7.4 错误处理
若用户输入的参数不符合要求,如忘记输入参数或输入非数字字符,程序可能会崩溃。在上述代码中,检查了参数数量,但对于输入非数字字符的情况,还需进一步处理。
综上所述,在 Java 编程中,合理运用数组、对象和命令行参数,能提高程序的灵活性和实用性。同时,需注意各种操作的细节和错误处理,以确保程序的稳定性。
8. 命令行参数的文件路径问题
8.1 不同操作系统的文件路径表示
在使用命令行参数指定文件路径时,不同操作系统有不同的路径表示方式。
-
Windows
:文件路径使用反斜杠
\
,但在 Java 的字符串中,需使用双反斜杠
\\
表示一个反斜杠。例如,要指定文件路径为
c:\MyNumberedFile.txt
,在 Java 代码中应写成
"c:\\MyNumberedFile.txt"
。
-
Linux 和 Macintosh
:文件路径使用正斜杠
/
,在 Java 字符串中直接使用一个正斜杠即可。例如,要指定 Macintosh 系统中 Documents 目录下的文件,可写成
"/Users/YourUserName/Documents/MyNumberedFile.txt"
。
8.2 文件保存位置
运行
MakeRandomNumsFile
程序后,生成的新文件
MyNumberedFile.txt
的保存位置取决于多种因素。若使用集成开发环境(IDE)且程序按项目划分,新文件通常位于项目文件夹中。可以修改代码来指定完整的文件路径,以确保文件保存到指定位置。
9. 命令行参数的类型转换
9.1 字符串转整数
在
MakeRandomNumsFile
程序中,
args[1]
是一个字符串类型的命令行参数,需要将其转换为整数类型才能用于计数。使用
Integer.parseInt
方法可以实现这一转换,示例代码如下:
int numLines = Integer.parseInt(args[1]);
9.2 类型转换的风险
若用户输入的
args[1]
不是有效的数字字符串,如输入了字母或其他非数字字符,调用
Integer.parseInt
方法会抛出
NumberFormatException
异常。因此,在实际应用中,需要对输入进行验证和异常处理。
10. 命令行参数的错误检查
10.1 检查参数数量
在
MakeRandomNumsFile
程序中,首先检查命令行参数的数量是否足够。若参数数量小于 2,程序会输出使用说明并退出,代码如下:
if (args.length < 2) {
System.out.println("Usage: MakeRandomNumsFile filename number");
System.exit(1);
}
10.2 检查参数类型
除了检查参数数量,还需要检查参数的类型是否符合要求。例如,
args[1]
必须是一个有效的整数。在当前代码中,虽然没有对
NumberFormatException
进行处理,但可以在后续优化中添加相应的异常处理逻辑。以下是添加异常处理后的代码示例:
import java.util.Random;
import java.io.PrintStream;
import java.io.IOException;
class MakeRandomNumsFile {
public static void main(String args[]) throws IOException {
Random generator = new Random();
if (args.length < 2) {
System.out.println("Usage: MakeRandomNumsFile filename number");
System.exit(1);
}
PrintStream printOut = new PrintStream(args[0]);
int numLines;
try {
numLines = Integer.parseInt(args[1]);
} catch (NumberFormatException e) {
System.out.println("The second argument must be a valid integer.");
System.exit(1);
}
for (int count = 1; count <= numLines; count++) {
printOut.println(generator.nextInt(10) + 1);
}
}
}
10.3 错误检查的流程
以下是命令行参数错误检查的流程图:
graph TD;
A[开始] --> B[检查参数数量];
B -- 参数数量不足 --> C[输出使用说明并退出];
B -- 参数数量足够 --> D[尝试转换参数类型];
D -- 转换成功 --> E[执行程序逻辑];
D -- 转换失败 --> F[输出错误信息并退出];
11. 总结
通过以上内容,我们了解了 Java 编程中数组、对象和命令行参数的使用方法和注意事项。以下是一个总结表格:
| 主题 | 关键知识点 | 示例代码 |
| ---- | ---- | ---- |
| 文件操作 |
PrintStream
构造函数处理文件的创建和覆盖;读取文件使用
Scanner
|
PrintStream printOut = new PrintStream("GuestList.txt");
Scanner diskScanner = new Scanner(new File("Employees.txt"));
|
| 数组条件表达式 | 注意条件表达式的顺序,避免错误 |
roomNum < 10 && guests[roomNum] != 0
|
| 面向对象编程 |
Room
类的定义和使用;创建对象数组的步骤 |
public class Room {...}
Room rooms[] = new Room[10];
|
| 数字格式化 | 使用
NumberFormat
类的
getCurrencyInstance
方法显示货币金额 |
NumberFormat currency = NumberFormat.getCurrencyInstance();
out.print(currency.format(rate));
|
| 条件运算符 | 接受三个表达式,根据条件返回其中一个表达式的值 |
smoking ? "yes" : "no"
|
| 命令行参数 | 从命令行获取额外信息;参数类型转换和错误检查 |
public static void main(String args[]) {...}
int numLines = Integer.parseInt(args[1]);
|
在实际编程中,要根据具体需求合理运用这些知识,并注意处理可能出现的错误和异常,以提高程序的健壮性和可靠性。同时,要根据不同的操作系统和环境,正确处理文件路径和参数输入,确保程序在各种情况下都能正常运行。
通过掌握这些知识,我们可以编写出更加灵活、高效和稳定的 Java 程序,应对各种复杂的编程场景。
超级会员免费看
1058

被折叠的 条评论
为什么被折叠?



