变量可能尚未使用输入数据初始化
Variable might not have been initialized using input data
public class Activity2PayStub
{
public static final double OVERTIME_RATE = 1.5;
public static final double SS_WITHHOLDING = .1;
public static final double FEDERAL_TAX = .2;
private String name;
private String ssn;
private int regHours;
private int overHours;
private double hourlyRate;
private double regPay = regHours * hourlyRate;
private double overRate = hourlyRate * OVERTIME_RATE;
private double overPay = overHours * OVERTIME_RATE * hourlyRate;
private double grossPay = regPay + overPay;
private double ssWith = grossPay * SS_WITHHOLDING;
private double fedTax = (grossPay - ssWith) * FEDERAL_TAX;
private double netPay = grossPay - ssWith - fedTax;
/**
* It all starts with the main method.
*
* @param args command-line arguments (not used)
*/
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
//Create an Activity2Paystub object
//a2ps is an Activity2PayStub object
Activity2PayStub a2ps = new Activity2PayStub();
//call the methods inside of an Activity2PayStub object
a2ps.getInput(keyboard);
a2ps.calculate();
a2ps.printPayStub();
}
public void getInput(Scanner keyboard)
{
System.out.print("Enter employee name: ");
name = keyboard.nextLine();
System.out.print("Enter employee SSN (incl. hyphens): ");
ssn = keyboard.nextLine();
int regHours;
System.out.print("Enter number of regular hours worked: ");
regHours = keyboard.nextInt();
System.out.print("Enter number of overtime hours worked: ");
overHours = keyboard.nextInt();
System.out.print("Enter hourly pay rate: ");
hourlyRate = keyboard.nextDouble();
}
public void calculate()
{
int regHours;
int overHours;
double hourlyRate;
double regPay = regHours * hourlyRate;
double overRate = hourlyRate * OVERTIME_RATE;
double overPay = overHours * OVERTIME_RATE * hourlyRate;
double grossPay = regPay + overPay;
double ssWith = grossPay * SS_WITHHOLDING;
double fedTax = (grossPay - ssWith) * FEDERAL_TAX;
double netPay = grossPay - ssWith - fedTax;
}
我在以下位置遇到问题:
双 regPay = regHours * hourlyRate;
双倍超额支付 = 超额工作时间 * OVERTIME_RATE * hourlyRate;
我遇到的问题是 regHours、hourlyRate 和 overHours 可能尚未初始化。
我正在尝试获取用户输入,那么我将如何初始化它们。
初始化所有必要的值,或稍后将代码移至运行
您的代码如:
private double regPay = regHours * hourlyRate;
private double overRate = hourlyRate * OVERTIME_RATE;
private double overPay = overHours * OVERTIME_RATE * hourlyRate;
…通过执行赋值右边的代码=
来赋值。实例化此 class 的对象时的代码 运行s。因此,当 运行s 以上的第一个示例行时,它正在尝试使用 regHours
和 hourlyRate
。但是那些 成员字段尚未分配 值。
private int regHours;
private int overHours;
private double hourlyRate;
所以你需要了解 class.
的生命周期
- 当 class 首次由 JVM class loader 加载时,您的
static
variables/constants 已建立。
- 当通过
new
实例化此 class 的对象时,首先是那些声明行 运行,然后是构造函数。
- 然后你的方法 运行 被调用。
如果您无法在声明时为所有必需的变量初始化值,则将您的计算代码移至构造函数。
如果您不知道构造时的初始值,请将您的代码移动到某个可以在适当时间调用的方法。
示例代码
这是您的代码的稍微清理过的版本。这是快速而肮脏的。我没有验证你的逻辑,也没有做任何测试。
package work.basil.example.paystub;
import java.util.Objects;
public class PayStub
{
public static final double OVERTIME_MULTIPLIER = 1.5, WITHHOLDING_MULTIPLIER = .1, FEDERAL_TAX = .2;
// inputs
private String name, employeeId;
private int regHours, overHours;
private double hourlyRate;
// results
// In real work, we would be using `BigDecimal` or integers for money, never `double`/`float`.
private double overRate, regPay, overPay, grossPay, withholdingAmount, fedTax, netPay;
public PayStub ( String name , String employeeId , int regHours , int overHours , double hourlyRate )
{
// In real work, we would do more data-validation. For example, checking for minimum, maximum, or unreasonable values.
this.name = Objects.requireNonNull( name );
this.employeeId = Objects.requireNonNull( employeeId );
this.regHours = Objects.requireNonNull( regHours );
this.overHours = Objects.requireNonNull( overHours );
this.hourlyRate = Objects.requireNonNull( hourlyRate );
this.calculate();
}
public void calculate ( )
{
this.regPay = regHours * hourlyRate;
this.overRate = hourlyRate * OVERTIME_MULTIPLIER;
this.overPay = overHours * hourlyRate;
this.grossPay = regPay + overPay;
this.withholdingAmount = grossPay * WITHHOLDING_MULTIPLIER;
this.fedTax = ( grossPay - withholdingAmount ) * FEDERAL_TAX;
this.netPay = grossPay - withholdingAmount - fedTax;
}
// Getters
public String getName ( ) { return this.name; }
public String getEmployeeId ( ) { return this.employeeId; }
public int getRegHours ( ) { return this.regHours; }
public int getOverHours ( ) { return this.overHours; }
public double getHourlyRate ( ) { return this.hourlyRate; }
public double getOverRate ( ) { return this.overRate; }
public double getRegPay ( ) { return this.regPay; }
public double getOverPay ( ) { return this.overPay; }
public double getGrossPay ( ) { return this.grossPay; }
public double getWithholdingAmount ( ) { return this.withholdingAmount; }
public double getFedTax ( ) { return this.fedTax; }
public double getNetPay ( ) { return this.netPay; }
// `Object` overrides
@Override
public String toString ( )
{
return "PayStub{ " +
"name='" + name + '\'' +
" | employeeId='" + employeeId + '\'' +
" | regHours=" + regHours +
" | overHours=" + overHours +
" | hourlyRate=" + hourlyRate +
" | overRate=" + overRate +
" | regPay=" + regPay +
" | overPay=" + overPay +
" | grossPay=" + grossPay +
" | withholdingAmount=" + withholdingAmount +
" | fedTax=" + fedTax +
" | netPay=" + netPay +
" }";
}
}
正在处理用户的数据输入。
此代码使用 Java 16 及更高版本中的新 records 功能。记录是编写 class 的一种简短方式,其主要目的是透明且不可变地携带数据。编译器隐式创建构造函数、getter、equals
& hashCode
和 toString
.
package work.basil.example.paystub;
import java.util.Objects;
import java.util.Scanner;
public class PayStubDataEntry
{
/**
* It all starts with the main method.
*
* @param args command-line arguments (not used)
*/
public static void main ( String[] args )
{
try(
Scanner scanner = new Scanner( System.in );
) {
PayStubDataEntry app = new PayStubDataEntry();
PayStubInput input = app.gatherInput( scanner );
PayStub payStub = new PayStub(
input.name,
input.employeeId,
input.regHours,
input.overhours,
input.hourlyRate
);
// Report pay stub results.
System.out.println( "payStub = " + payStub );
}
}
public PayStubInput gatherInput ( Scanner keyboard )
{
System.out.print( "Enter employee name: " );
String name = keyboard.nextLine();
System.out.print( "Enter employee identifier (incl. hyphens): " );
String employeeId = keyboard.nextLine();
System.out.print( "Enter number of regular hours worked: " );
int regHours = keyboard.nextInt();
System.out.print( "Enter number of overtime hours worked: " );
int overHours = keyboard.nextInt();
System.out.print( "Enter hourly pay rate: " );
double hourlyRate = keyboard.nextDouble();
PayStubInput input = new PayStubInput(
Objects.requireNonNull( name ) ,
Objects.requireNonNull( employeeId ) ,
Objects.requireNonNull( regHours ) ,
Objects.requireNonNull( overHours ) ,
Objects.requireNonNull( hourlyRate )
);
return input ;
}
record PayStubInput(String name , String employeeId , int regHours , int overhours , double hourlyRate)
{
}
}
当运行。可以看到这个例子中浮点数不准确的问题运行.
Enter employee name: Basil
Enter employee identifier (incl. hyphens): AGENT-007
Enter number of regular hours worked: 40
Enter number of overtime hours worked: 12
Enter hourly pay rate: 7
payStub = PayStub{ name='Basil' | employeeId='AGENT-007' | regHours=40 | overHours=12 | hourlyRate=7.0 | overRate=10.5 | regPay=280.0 | overPay=84.0 | grossPay=364.0 | withholdingAmount=36.4 | fedTax=65.52000000000001 | netPay=262.08000000000004 }
不相关的提示
类 最好写成专注于特定的工作。这被称为 single-responsibility principle (SRP)。因此,PayStub
class 应该专注于了解如何正确表示工资单。它不应该知道与控制台上的用户交互。因此,将该扫描器代码拉出到另一个 class.
社会安全号码 (SSN) 应作为敏感数据保密。这就是为什么员工在加入公司时会被分配员工编号。
切勿使用 double
/Double
或 float
/Float
换钱。这些类型使用浮点技术 trade away accuracy 来提高执行速度。会计师更喜欢准确性。相反,要么使用 BigDecimal
class,要么将货币值乘以便士等整数。
注意你的命名。您的常量 OVERTIME_RATE
用词不当。该值是您确定实际加班费率的乘数。我想簿记员对此会有一个术语,但我不知道。如果不出意外,就称它为OVERTIME_MULTIPLIER
。如果您对名称不满意,不确定它是否crystal-清晰和具体,这表明您可能不了解业务问题的某些方面。
您忽略了跟踪支付期信息。为此使用 java.time classes,可能 LocalDate
.
一个Scanner
object is a resource that should be closed when no longer needed. As a good habit, use try-with-resources syntax to automatically call its close
method. This works because Scanner
implements AutoCloseable
.
public class Activity2PayStub
{
public static final double OVERTIME_RATE = 1.5;
public static final double SS_WITHHOLDING = .1;
public static final double FEDERAL_TAX = .2;
private String name;
private String ssn;
private int regHours;
private int overHours;
private double hourlyRate;
private double regPay = regHours * hourlyRate;
private double overRate = hourlyRate * OVERTIME_RATE;
private double overPay = overHours * OVERTIME_RATE * hourlyRate;
private double grossPay = regPay + overPay;
private double ssWith = grossPay * SS_WITHHOLDING;
private double fedTax = (grossPay - ssWith) * FEDERAL_TAX;
private double netPay = grossPay - ssWith - fedTax;
/**
* It all starts with the main method.
*
* @param args command-line arguments (not used)
*/
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
//Create an Activity2Paystub object
//a2ps is an Activity2PayStub object
Activity2PayStub a2ps = new Activity2PayStub();
//call the methods inside of an Activity2PayStub object
a2ps.getInput(keyboard);
a2ps.calculate();
a2ps.printPayStub();
}
public void getInput(Scanner keyboard)
{
System.out.print("Enter employee name: ");
name = keyboard.nextLine();
System.out.print("Enter employee SSN (incl. hyphens): ");
ssn = keyboard.nextLine();
int regHours;
System.out.print("Enter number of regular hours worked: ");
regHours = keyboard.nextInt();
System.out.print("Enter number of overtime hours worked: ");
overHours = keyboard.nextInt();
System.out.print("Enter hourly pay rate: ");
hourlyRate = keyboard.nextDouble();
}
public void calculate()
{
int regHours;
int overHours;
double hourlyRate;
double regPay = regHours * hourlyRate;
double overRate = hourlyRate * OVERTIME_RATE;
double overPay = overHours * OVERTIME_RATE * hourlyRate;
double grossPay = regPay + overPay;
double ssWith = grossPay * SS_WITHHOLDING;
double fedTax = (grossPay - ssWith) * FEDERAL_TAX;
double netPay = grossPay - ssWith - fedTax;
}
我在以下位置遇到问题: 双 regPay = regHours * hourlyRate; 双倍超额支付 = 超额工作时间 * OVERTIME_RATE * hourlyRate;
我遇到的问题是 regHours、hourlyRate 和 overHours 可能尚未初始化。
我正在尝试获取用户输入,那么我将如何初始化它们。
初始化所有必要的值,或稍后将代码移至运行
您的代码如:
private double regPay = regHours * hourlyRate;
private double overRate = hourlyRate * OVERTIME_RATE;
private double overPay = overHours * OVERTIME_RATE * hourlyRate;
…通过执行赋值右边的代码=
来赋值。实例化此 class 的对象时的代码 运行s。因此,当 运行s 以上的第一个示例行时,它正在尝试使用 regHours
和 hourlyRate
。但是那些 成员字段尚未分配 值。
private int regHours;
private int overHours;
private double hourlyRate;
所以你需要了解 class.
的生命周期- 当 class 首次由 JVM class loader 加载时,您的
static
variables/constants 已建立。 - 当通过
new
实例化此 class 的对象时,首先是那些声明行 运行,然后是构造函数。 - 然后你的方法 运行 被调用。
如果您无法在声明时为所有必需的变量初始化值,则将您的计算代码移至构造函数。
如果您不知道构造时的初始值,请将您的代码移动到某个可以在适当时间调用的方法。
示例代码
这是您的代码的稍微清理过的版本。这是快速而肮脏的。我没有验证你的逻辑,也没有做任何测试。
package work.basil.example.paystub;
import java.util.Objects;
public class PayStub
{
public static final double OVERTIME_MULTIPLIER = 1.5, WITHHOLDING_MULTIPLIER = .1, FEDERAL_TAX = .2;
// inputs
private String name, employeeId;
private int regHours, overHours;
private double hourlyRate;
// results
// In real work, we would be using `BigDecimal` or integers for money, never `double`/`float`.
private double overRate, regPay, overPay, grossPay, withholdingAmount, fedTax, netPay;
public PayStub ( String name , String employeeId , int regHours , int overHours , double hourlyRate )
{
// In real work, we would do more data-validation. For example, checking for minimum, maximum, or unreasonable values.
this.name = Objects.requireNonNull( name );
this.employeeId = Objects.requireNonNull( employeeId );
this.regHours = Objects.requireNonNull( regHours );
this.overHours = Objects.requireNonNull( overHours );
this.hourlyRate = Objects.requireNonNull( hourlyRate );
this.calculate();
}
public void calculate ( )
{
this.regPay = regHours * hourlyRate;
this.overRate = hourlyRate * OVERTIME_MULTIPLIER;
this.overPay = overHours * hourlyRate;
this.grossPay = regPay + overPay;
this.withholdingAmount = grossPay * WITHHOLDING_MULTIPLIER;
this.fedTax = ( grossPay - withholdingAmount ) * FEDERAL_TAX;
this.netPay = grossPay - withholdingAmount - fedTax;
}
// Getters
public String getName ( ) { return this.name; }
public String getEmployeeId ( ) { return this.employeeId; }
public int getRegHours ( ) { return this.regHours; }
public int getOverHours ( ) { return this.overHours; }
public double getHourlyRate ( ) { return this.hourlyRate; }
public double getOverRate ( ) { return this.overRate; }
public double getRegPay ( ) { return this.regPay; }
public double getOverPay ( ) { return this.overPay; }
public double getGrossPay ( ) { return this.grossPay; }
public double getWithholdingAmount ( ) { return this.withholdingAmount; }
public double getFedTax ( ) { return this.fedTax; }
public double getNetPay ( ) { return this.netPay; }
// `Object` overrides
@Override
public String toString ( )
{
return "PayStub{ " +
"name='" + name + '\'' +
" | employeeId='" + employeeId + '\'' +
" | regHours=" + regHours +
" | overHours=" + overHours +
" | hourlyRate=" + hourlyRate +
" | overRate=" + overRate +
" | regPay=" + regPay +
" | overPay=" + overPay +
" | grossPay=" + grossPay +
" | withholdingAmount=" + withholdingAmount +
" | fedTax=" + fedTax +
" | netPay=" + netPay +
" }";
}
}
正在处理用户的数据输入。
此代码使用 Java 16 及更高版本中的新 records 功能。记录是编写 class 的一种简短方式,其主要目的是透明且不可变地携带数据。编译器隐式创建构造函数、getter、equals
& hashCode
和 toString
.
package work.basil.example.paystub;
import java.util.Objects;
import java.util.Scanner;
public class PayStubDataEntry
{
/**
* It all starts with the main method.
*
* @param args command-line arguments (not used)
*/
public static void main ( String[] args )
{
try(
Scanner scanner = new Scanner( System.in );
) {
PayStubDataEntry app = new PayStubDataEntry();
PayStubInput input = app.gatherInput( scanner );
PayStub payStub = new PayStub(
input.name,
input.employeeId,
input.regHours,
input.overhours,
input.hourlyRate
);
// Report pay stub results.
System.out.println( "payStub = " + payStub );
}
}
public PayStubInput gatherInput ( Scanner keyboard )
{
System.out.print( "Enter employee name: " );
String name = keyboard.nextLine();
System.out.print( "Enter employee identifier (incl. hyphens): " );
String employeeId = keyboard.nextLine();
System.out.print( "Enter number of regular hours worked: " );
int regHours = keyboard.nextInt();
System.out.print( "Enter number of overtime hours worked: " );
int overHours = keyboard.nextInt();
System.out.print( "Enter hourly pay rate: " );
double hourlyRate = keyboard.nextDouble();
PayStubInput input = new PayStubInput(
Objects.requireNonNull( name ) ,
Objects.requireNonNull( employeeId ) ,
Objects.requireNonNull( regHours ) ,
Objects.requireNonNull( overHours ) ,
Objects.requireNonNull( hourlyRate )
);
return input ;
}
record PayStubInput(String name , String employeeId , int regHours , int overhours , double hourlyRate)
{
}
}
当运行。可以看到这个例子中浮点数不准确的问题运行.
Enter employee name: Basil
Enter employee identifier (incl. hyphens): AGENT-007
Enter number of regular hours worked: 40
Enter number of overtime hours worked: 12
Enter hourly pay rate: 7
payStub = PayStub{ name='Basil' | employeeId='AGENT-007' | regHours=40 | overHours=12 | hourlyRate=7.0 | overRate=10.5 | regPay=280.0 | overPay=84.0 | grossPay=364.0 | withholdingAmount=36.4 | fedTax=65.52000000000001 | netPay=262.08000000000004 }
不相关的提示
类 最好写成专注于特定的工作。这被称为 single-responsibility principle (SRP)。因此,PayStub
class 应该专注于了解如何正确表示工资单。它不应该知道与控制台上的用户交互。因此,将该扫描器代码拉出到另一个 class.
社会安全号码 (SSN) 应作为敏感数据保密。这就是为什么员工在加入公司时会被分配员工编号。
切勿使用 double
/Double
或 float
/Float
换钱。这些类型使用浮点技术 trade away accuracy 来提高执行速度。会计师更喜欢准确性。相反,要么使用 BigDecimal
class,要么将货币值乘以便士等整数。
注意你的命名。您的常量 OVERTIME_RATE
用词不当。该值是您确定实际加班费率的乘数。我想簿记员对此会有一个术语,但我不知道。如果不出意外,就称它为OVERTIME_MULTIPLIER
。如果您对名称不满意,不确定它是否crystal-清晰和具体,这表明您可能不了解业务问题的某些方面。
您忽略了跟踪支付期信息。为此使用 java.time classes,可能 LocalDate
.
一个Scanner
object is a resource that should be closed when no longer needed. As a good habit, use try-with-resources syntax to automatically call its close
method. This works because Scanner
implements AutoCloseable
.