
在java编程中,初学者有时会将scanner对象的创建和输入操作直接放置在类的成员变量声明处或实例初始化块中。例如:
public class MyClass {
Scanner myObj = new Scanner(System.in); // Scanner创建在成员变量声明处
{
System.out.print("Enter value: "); // 实例初始化块中的输出
}
int value = myObj.nextInt(); // 输入操作
// ... 其他成员变量和方法
}当程序在main方法中多次创建MyClass的实例时,例如:
public static void main(String[] args) {
MyClass a = new MyClass();
MyClass b = new MyClass();
MyClass c = new MyClass();
// ...
}每次执行new MyClass()时,Java虚拟机都会执行以下步骤来初始化新创建的对象:
因此,如果将Scanner的创建、输入提示和实际输入操作放在成员变量声明或实例初始化块中,那么每当创建一个新的对象实例时,这些操作都会被重复执行一遍,导致用户界面出现多次重复的输入提示和等待输入的情况,这与预期的单次输入行为不符。
为了避免上述问题,推荐的做法是将对象的初始化逻辑(包括需要用户输入的成员变量)放置在类的构造器中。构造器是专门用于创建对象时进行初始化的特殊方法。
立即学习“Java免费学习笔记(深入)”;
构造器在对象被创建时自动调用,允许我们在对象实例化时传入必要的参数,并对对象的成员变量进行赋值。这使得对象的初始化过程更加可控和清晰。
Scanner对象通常用于从标准输入(System.in)读取数据。一个应用程序通常只需要一个Scanner实例来处理标准输入。因此,建议在程序的入口点(通常是main方法)创建Scanner实例,并将其作为参数传递给需要它的对象构造器或方法。这样可以避免创建多个不必要的Scanner实例,并且便于统一管理和关闭资源。
以下是遵循最佳实践的重构代码示例:
import java.util.Scanner;
public class CaratConverter {
// 声明成员变量,但不在此处进行初始化
private int caratValue;
private double gramsPerCarat = 0.20;
private double caratsInGrams;
private double gramsInMilligrams;
private double milligramsInPounds;
/**
* 构造器:用于初始化CaratConverter对象。
* 接收一个Scanner实例,以便从外部获取输入。
*
* @param scanner 用于获取用户输入的Scanner对象
*/
public CaratConverter(Scanner scanner) {
System.out.print("Enter Carat Value: ");
this.caratValue = scanner.nextInt(); // 通过传入的Scanner获取输入
// 根据输入值计算其他派生属性
this.caratsInGrams = this.caratValue * this.gramsPerCarat;
this.gramsInMilligrams = this.caratsInGrams * 1000;
this.milligramsInPounds = this.gramsInMilligrams * 0.00220462 / 1000;
// 可以在构造器中直接打印结果,或者通过getter方法在main方法中打印
System.out.println("Carats in Grams: " + this.caratsInGrams);
System.out.println("Grams in Milligrams: " + this.gramsInMilligrams);
System.out.println("Milligrams in Pounds: " + this.milligramsInPounds);
}
// 可以添加getter方法来获取计算结果,如果需要在外部访问
public double getCaratsInGrams() {
return caratsInGrams;
}
public double getGramsInMilligrams() {
return gramsInMilligrams;
}
public double getMilligramsInPounds() {
return milligramsInPounds;
}
public static void main(String[] args) {
// 在main方法中创建并管理Scanner实例
Scanner mainScanner = new Scanner(System.in);
// 只创建一次CaratConverter对象,并传入Scanner
// 构造器中的逻辑将只执行一次输入和计算
new CaratConverter(mainScanner);
// 如果需要创建多个CaratConverter实例,并且每个实例都需要独立的输入,
// 则每次创建时都会触发输入,但这通常不是预期行为。
// 如果只是为了展示不同的计算结果,可以创建对象后通过setter或构造器参数设置值。
// 例如:
// CaratConverter converter1 = new CaratConverter(mainScanner); // 第一次输入
// CaratConverter converter2 = new CaratConverter(mainScanner); // 第二次输入
// 重要的:在使用完毕后关闭Scanner,释放系统资源
mainScanner.close();
}
}代码解释:
通过遵循这些最佳实践,可以编写出更健壮、更易于理解和维护的Java应用程序。
以上就是Java中Scanner的正确使用与对象初始化最佳实践的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号