
在Java中,直接在类定义中声明并初始化非static的字段(也称为实例初始化器或字段初始化器),或者使用实例初始化块({}代码块),这些代码会在每次创建该类的新实例时执行。当Scanner对象的创建和输入操作被放置在这些位置时,就会导致每次实例化对象时都重复进行输入提示。
考虑以下示例代码,它展示了这种常见的问题模式:
package galitkami;
import java.util.Scanner;
public class test {
Scanner myObj = new Scanner(System.in); // 实例字段初始化
{System.out.print("Enter Carat Value: ");} // 实例初始化块
int c = myObj.nextInt(); // 实例字段初始化,执行输入
double g = 0.20;
double cg = c*g;
double gm = cg*1000;
double mg = gm*0.00220462/1000;
public static void main(String[] args) {
test a = new test(); // 第一次实例化,执行一次输入
test b = new test(); // 第二次实例化,执行第二次输入
test c = new test(); // 第三次实例化,执行第三次输入
System.out.println("Carats in Grams: "+a.cg);
System.out.println("Grams in Milligrams: "+b.gm);
System.out.println("Milligrams in Pounds: "+c.mg);
}
}在上述代码中,Scanner myObj = new Scanner(System.in);、{System.out.print("Enter Carat Value: ");} 和 int c = myObj.nextInt(); 都属于实例初始化的一部分。当main方法中执行new test()三次时,这些初始化逻辑会被重复执行三次,从而导致程序三次提示用户输入。这不仅造成了不必要的重复操作,也违背了程序设计的直观逻辑。
为了解决上述问题并遵循良好的编程实践,我们应该将对象的初始化逻辑,特别是涉及用户输入和资源(如Scanner)管理的逻辑,放置在更合适的位置。
立即学习“Java免费学习笔记(深入)”;
构造方法是Java中用于初始化新创建对象状态的特殊方法。它是执行对象创建后立即运行的代码块,是设置对象初始属性值的理想场所。通过将输入逻辑放入构造方法,我们可以更精确地控制何时进行输入。
import java.util.Scanner;
public class Test { // 建议类名首字母大写
// 声明类属性,但不在此处初始化,等待构造方法或特定方法进行初始化
int c;
double g, cg, gm, mg;
// 类构造方法:用于初始化Test对象
// 接受一个Scanner对象作为参数,避免在构造方法内部重复创建Scanner
public Test(Scanner myObj) {
System.out.print("Enter Carat Value: ");
c = myObj.nextInt(); // 在构造方法中获取输入
// 根据输入值计算其他属性
g = 0.20;
cg = c * g;
gm = cg * 1000;
mg = gm * 0.00220462 / 1000;
// 可以在构造方法中直接打印结果,或者在main方法中访问对象属性后打印
System.out.println("Carats in Grams: " + cg);
System.out.println("Grams in Milligrams: " + gm);
System.out.println("Milligrams in Pounds: " + mg);
}
public static void main(String[] args) {
// 在main方法中创建并管理唯一的Scanner实例
Scanner myObj = new Scanner(System.in);
// 通过调用构造方法创建Test对象,此时构造方法中的逻辑(包括输入)会被执行
// 如果只需要一次输入并计算,只需创建一个Test对象
new Test(myObj); // 创建一个Test对象并执行其构造方法
// 如果需要创建多个Test对象,且每个对象都需要独立输入,则可以多次调用构造方法
// Test test1 = new Test(myObj);
// Test test2 = new Test(myObj); // 这将再次提示输入
// 重要:使用完毕后关闭Scanner,释放系统资源
myObj.close();
}
}代码解释:
在某些情况下,如果确实需要Scanner在整个应用程序生命周期内只被初始化一次,并且其输入不与特定对象实例绑定,可以将其声明为static。
import java.util.Scanner;
public class TestStaticScanner {
static Scanner myObj = new Scanner(System.in); // 静态字段初始化,只执行一次
// 静态初始化块,只在类加载时执行一次
static {
System.out.print("Enter Carat Value (Static): ");
}
final int c = myObj.nextInt(); // 实例字段初始化,但myObj已在静态初始化时准备好
double g = 0.20;
double cg = c * g;
double gm = cg * 1000;
double mg = gm * 0.00220462 / 1000;
public static void main(String[] args) {
// 即使创建多个TestStaticScanner对象,输入也只发生一次
TestStaticScanner a = new TestStaticScanner();
TestStaticScanner b = new TestStaticScanner(); // 不会再次提示输入
TestStaticScanner c = new TestStaticScanner(); // 不会再次提示输入
System.out.println("Carats in Grams: " + a.cg);
System.out.println("Grams in Milligrams: " + a.gm);
System.out.println("Milligrams in Pounds: " + a.mg);
myObj.close(); // 关闭静态Scanner
}
}注意:
为了编写健壮、可维护的Java代码,请遵循以下建议:
通过采纳这些实践,您可以有效地管理Java中的输入流,避免常见的陷阱,并构建结构更清晰、行为更可预测的应用程序。
以上就是Java中Scanner与对象实例化:避免重复输入和提升代码结构的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号