Java程序设计题解与上机指导
本指南旨在通过一系列由浅入深的上机实验和编程题,帮助学习者巩固Java语言的核心概念,提升编程实践能力和问题解决能力。

第一部分:Java开发环境搭建
在开始编程之前,必须先准备好开发环境。
安装JDK (Java Development Kit)
- 作用: JDK是Java的核心,包含了编译器(
javac)、运行时环境(JRE)和开发工具。 - 下载: 访问Oracle官网或OpenJDK官网,下载与你操作系统匹配的最新LTS(长期支持)版本。
- 配置环境变量:
JAVA_HOME: 指向JDK的安装根目录(C:\Program Files\Java\jdk-17)。Path: 添加%JAVA_HOME%\bin,这样系统才能在任何位置识别java和javac命令。
- 验证: 打开命令行,输入
java -version和javac -version,如果显示版本号,则安装成功。
选择开发工具
- 集成开发环境: 强烈推荐使用IDE,它们能提供代码提示、调试、自动编译等强大功能,极大提高效率。
- IntelliJ IDEA (社区版免费): 功能最强大,智能程度最高,是目前Java开发的首选。
- Eclipse: 经典老牌IDE,免费开源,插件生态丰富。
- VS Code: 轻量级,通过插件支持Java开发,适合追求简洁的开发者。
第二部分:经典上机实验与题解
以下实验按照Java学习的典型顺序编排,每个实验都包含实验目的、内容、代码示例和关键知识点。
Java基础语法与流程控制
实验目的
- 掌握Java程序的基本结构。
- 熟练使用基本数据类型、变量、运算符。
- 掌握
if-else、switch、for、while、do-while等流程控制语句。
- Hello World: 编写第一个Java程序,在控制台打印"Hello, World!"。
- 数字计算: 编写程序,从键盘接收两个整数,计算并输出它们的和、差、积、商和余数。
- 成绩等级判断: 输入一个学生的成绩(0-100),使用
if-else判断并输出其等级(A: 90-100, B: 80-89, C: 60-79, D: <60)。 - 猜数字游戏: 生成一个1-100的随机整数,让用户猜测,并提示“猜大了”或“猜小了”,直到猜对为止。
代码题解与知识点 2: 数字计算**

import java.util.Scanner; // 1. 导入Scanner类,用于接收键盘输入
public class Calculator {
public static void main(String[] args) {
// 2. 创建Scanner对象
Scanner scanner = new Scanner(System.in);
// 3. 提示用户输入并读取数据
System.out.print("请输入第一个整数: ");
int num1 = scanner.nextInt();
System.out.print("请输入第二个整数: ");
int num2 = scanner.nextInt();
// 4. 进行计算
int sum = num1 + num2;
int difference = num1 - num2;
int product = num1 * num2;
// 注意:整数除法会丢失小数部分
int quotient = num1 / num2;
int remainder = num1 % num2;
// 5. 输出结果
System.out.println("和: " + sum);
System.out.println("差: " + difference);
System.out.println("积: " + product);
System.out.println("商: " + quotient);
System.out.println("余数: " + remainder);
// 6. 关闭Scanner,释放资源
scanner.close();
}
}
关键知识点:
import语句:引入Java标准库中的类。Scanner类:用于获取用户的控制台输入。nextInt(),nextDouble(),nextLine():用于读取不同类型的数据。- 基本算术运算符:, , , , 。
- 字符串拼接:使用 号可以将任何类型与字符串拼接。
4: 猜数字游戏**
import java.util.Random;
import java.util.Scanner;
public class GuessNumber {
public static void main(String[] args) {
// 1. 生成随机数
Random random = new Random();
int targetNumber = random.nextInt(100) + 1; // 生成1-100的随机数
Scanner scanner = new Scanner(System.in);
int guess = 0;
int attempts = 0;
System.out.println("欢迎来到猜数字游戏!我已经想好了一个1-100之间的数字。");
// 2. 使用while循环,直到猜对为止
while (guess != targetNumber) {
System.out.print("请输入你的猜测: ");
guess = scanner.nextInt();
attempts++;
if (guess > targetNumber) {
System.out.println("猜大了!");
} else if (guess < targetNumber) {
System.out.println("猜小了!");
} else {
System.out.println("恭喜你,猜对了!");
System.out.println("你总共猜了 " + attempts + " 次。");
}
}
scanner.close();
}
}
关键知识点:
java.util.Random类:用于生成伪随机数。while循环:在条件为true时重复执行代码块,非常适合“直到...才停止”的场景。- 条件判断:
if-else if-else结构。 - 计数器:使用一个变量(
attempts)来记录循环的次数。
数组与方法
实验目的

- 掌握一维数组和二维数组的声明、初始化和使用。
- 理解方法的定义、调用、参数传递和返回值。
- 能够将复杂功能分解为多个方法实现。
- 数组排序与查找: 创建一个包含10个随机整数的数组,实现冒泡排序对其进行升序排序,然后使用二分查找法查找用户指定的数字。
- 二维矩阵转置: 创建一个3x3的二维矩阵,编写方法将其转置(行列互换)并打印。
- 学生成绩管理: 创建一个学生类,包含姓名和成绩数组,编写方法计算平均分、最高分和最低分。
代码题解与知识点 1: 数组排序与查找**
import java.util.Arrays;
import java.util.Scanner;
public class ArraySortAndSearch {
public static void main(String[] args) {
int[] numbers = new int[10];
// ... (此处省略用随机数填充数组的代码) ...
System.out.println("原始数组: " + Arrays.toString(numbers));
// 1. 调用排序方法
bubbleSort(numbers);
System.out.println("排序后数组: " + Arrays.toString(numbers));
// 2. 调用查找方法
Scanner scanner = new Scanner(System.in);
System.out.print("请输入要查找的数字: ");
int target = scanner.nextInt();
int index = binarySearch(numbers, target);
if (index != -1) {
System.out.println("数字 " + target + " 在数组中的索引是: " + index);
} else {
System.out.println("数字 " + target + " 不在数组中。");
}
}
// 冒泡排序方法
public static 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;
}
}
}
}
// 二分查找方法 (前提:数组必须有序)
public static int binarySearch(int[] arr, int target) {
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1; // 未找到
}
}
关键知识点:
- 方法: 将功能封装起来,提高代码复用性和可读性。
public static void methodName(...): 定义一个静态无返回值方法。public static int methodName(...): 定义一个静态有返回值方法。return: 结束方法执行,并返回一个值。
- 数组作为参数: 方法可以接收数组作为参数,对数组的修改会影响原始数组。
Arrays.toString(): 快速打印数组内容。- 冒泡排序: 一种简单的排序算法,通过多次遍历交换相邻的逆序元素。
- 二分查找: 一种高效的查找算法,要求数组有序,每次将查找范围减半。
面向对象编程
实验目的
- 掌握类的定义和对象的创建。
- 理解封装、构造方法、
this关键字。 - 理解继承、多态、抽象类和接口。
- 设计“形状”体系: 定义一个抽象类
Shape,包含计算面积和周长的抽象方法,创建Circle(圆形)和Rectangle(矩形)子类,并实现这些方法,在主程序中,使用一个Shape数组来存放不同形状的对象,并调用它们的计算方法。 - “人”与“学生”: 定义
Person类(属性:姓名、年龄),定义Student类继承Person,并增加学号、专业属性,为Student类编写方法,展示其信息。
代码题解与知识点 1: 设计“形状”体系**
// Shape.java - 抽象类
public abstract class Shape {
// 抽象方法,没有方法体
public abstract double calculateArea();
public abstract double calculatePerimeter();
}
// Circle.java
public class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double calculateArea() {
return Math.PI * radius * radius;
}
@Override
public double calculatePerimeter() {
return 2 * Math.PI * radius;
}
@Override
public String toString() {
return "Circle [radius=" + radius + "]";
}
}
// Rectangle.java
public class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public double calculateArea() {
return width * height;
}
@Override
public double calculatePerimeter() {
return 2 * (width + height);
}
@Override
public String toString() {
return "Rectangle [width=" + width + ", height=" + height + "]";
}
}
// Main.java
public class ShapeTest {
public static void main(String[] args) {
// 使用多态:父类引用指向子类对象
Shape[] shapes = new Shape[2];
shapes[0] = new Circle(5.0);
shapes[1] = new Rectangle(4.0, 6.0);
for (Shape shape : shapes) {
System.out.println("对象: " + shape);
System.out.println("面积: " + shape.calculateArea());
System.out.println("周长: " + shape.calculatePerimeter());
System.out.println("----------------------");
}
}
}
关键知识点:
- 抽象类 (
abstract class): 不能被实例化,用于定义通用模板,包含抽象方法(只有声明,没有实现)和具体方法。 - 继承 (
extends): 子类继承父类的属性和方法,实现代码复用。 - 方法重写 (
@Override): 子类提供与父类方法签名相同但实现不同的方法。 - 多态: 同一个接口,使用不同的实例而执行不同操作。
Shape[] shapes = new Shape[2];就是多态的体现,它使得程序更具扩展性。 - 构造方法: 与类同名,用于创建和初始化对象。
常用API与异常处理
实验目的
- 掌握
String、StringBuilder、Date、ArrayList等常用类的使用。 - 理解异常的机制,学会使用
try-catch-finally进行异常处理。
- 字符串处理: 编写程序,接收一个用户输入的字符串,统计其中英文字母、数字、空格和其他字符的数量。
- 集合操作: 创建一个
ArrayList,向其中添加10个随机字符串,然后将其反转并打印。 - 文件读取与异常处理: 编写程序尝试读取一个不存在的文件,并捕获
FileNotFoundException,给出友好的错误提示。
代码题解与知识点 2: 集合操作**
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
public class ArrayListDemo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Random random = new Random();
// 添加10个随机字符串
for (int i = 0; i < 10; i++) {
// 生成一个5-10个字符的随机字符串
int length = random.nextInt(6) + 5;
StringBuilder sb = new StringBuilder();
for (int j = 0; j < length; j++) {
char c = (char) (random.nextInt(26) + 'a');
sb.append(c);
}
list.add(sb.toString());
}
System.out.println("原始列表: " + list);
// 反转列表
Collections.reverse(list);
System.out.println("反转后列表: " + list);
}
}
关键知识点:
ArrayList: Java中最常用的动态数组集合,可以自动扩容。Collections工具类: 提供了操作集合的静态方法,如sort(),reverse(),max()等。StringBuilder: 用于高效地拼接字符串,比直接使用号连接字符串性能更好。 3: 文件读取与异常处理**
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class FileReadDemo {
public static void main(String[] args) {
File file = new File("non_existent_file.txt");
try {
Scanner scanner = new Scanner(file);
System.out.println("文件内容: " + scanner.nextLine());
scanner.close();
} catch (FileNotFoundException e) {
// 捕获特定的异常
System.err.println("错误: 文件未找到!请检查文件路径是否正确。");
// e.printStackTrace(); // 打印详细的错误堆栈信息,用于调试
} finally {
// 无论是否发生异常,finally块中的代码都会执行
System.out.println("文件读取操作结束。");
}
}
}
关键知识点:
- 异常: 程序运行时发生的不正常事件。
try-catch-finally:try: 将可能抛出异常的代码块包裹起来。catch: 捕获特定类型的异常,并进行处理。finally: 用于执行必须完成的清理操作,如关闭资源。
FileNotFoundException: 当尝试访问一个不存在的文件时,Scanner会抛出此异常。
第三部分:综合项目实践
将所学知识融会贯通,完成一个完整的项目是最好的学习方式。
项目:简易图书管理系统
项目目标 开发一个控制台版的图书管理系统,实现对图书的增、删、改、查功能。
功能需求
- 图书信息: 每本书包含
id(唯一标识),title(书名),author(作者),price(价格)。 - 添加图书: 通过控制台输入图书信息,添加到系统中。
- 查看所有图书: 列出系统中所有图书的信息。
- 根据ID查找图书: 输入图书ID,显示该书的详细信息。
- 删除图书: 输入图书ID,从系统中删除该书。
- 退出系统: 退出程序。
技术栈
- 数据存储: 使用
ArrayList<Book>来存储图书对象。 - 用户交互: 使用
Scanner获取用户输入。 - 面向对象: 创建
Book类来封装图书数据,可以创建一个BookManager类来管理所有业务逻辑。
项目结构
BookManager/
├── Book.java // 图书实体类
├── BookManager.java // 图书管理类,包含核心业务逻辑
└── Main.java // 程序入口,显示菜单并调用管理类
实现思路
- 创建
Book类:public class Book { private String id; private String title; private String author; private double price; // 构造方法、Getter和Setter方法、toString()方法 } - 创建
BookManager类:- 成员变量:
private ArrayList<Book> books = new ArrayList<>(); - 方法:
addBook(Book book): 添加图书。showAllBooks(): 遍历books列表并打印。findBookById(String id): 遍历查找,返回找到的Book对象或null。deleteBookById(String id): 查找并删除。
- 成员变量:
- 创建
Main类:- 创建
BookManager实例和Scanner实例。 - 使用
while(true)循环显示主菜单。 - 根据
Scanner读取的用户选择,调用BookManager中对应的方法。 - 使用
switch-case结构处理不同选项。
- 创建
扩展挑战
- 将图书数据保存到文件中,实现程序退出后数据不丢失(需要学习
FileWriter和ObjectOutputStream)。 - 增加按书名模糊查找功能。
- 增加修改图书信息的功能。
学习建议
- 动手敲代码: 不要只看不练,亲手将每个例子敲一遍,并尝试修改和扩展它。
- 调试是关键: 学会使用IDE的调试功能(设置断点、单步执行、查看变量值),这是解决复杂问题的利器。
- 善用官方文档: 遇到不熟悉的类或方法,第一时间查阅Oracle官方Java文档。
- 多思考,多总结: 每完成一个实验,思考一下它的核心知识点是什么?还有没有其他实现方式?为什么这样设计?
- 阅读优秀代码: 在GitHub等平台寻找一些简单的Java开源项目,阅读别人的代码,学习好的编程风格和设计思想。
希望这份详细的指南能对你的Java学习之路有所帮助!祝你编程愉快!
