变量可能尚未使用输入数据初始化

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 以上的第一个示例行时,它正在尝试使用 regHourshourlyRate。但是那些 成员字段尚未分配 值。

    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 & hashCodetoString.

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/Doublefloat/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.