Java Cannot make a static reference报错原因及解决方案
错误触发原因分析
main方法被static关键字修饰,属于类级别的方法,在类加载阶段就会完成初始化,调用时不需要依赖类的实例对象。而代码中定义的GrossPay、税率、薪资相关变量都是非静态的实例成员,只有当NetPay类被实例化(即创建出类的对象)后,这些成员变量才会分配内存完成初始化,可被访问。
静态方法的生命周期早于实例成员,因此在静态的main方法中直接访问未初始化的非静态实例字段,就会触发Cannot make a static reference to the non-static field GrossPay报错。
可行修复方案
这里提供两种常用的修复方式,同时附带数据类型优化的调整:
方案1:实例化NetPay类后访问实例成员(更推荐,符合面向对象设计,后续可灵活支持多组薪资计算)
仅需要修改main方法内部逻辑,先创建NetPay类的实例,再通过实例访问对应的成员变量即可,修改后完整代码如下:
public class NetPay { // 固定不变的税率、时薪参数加final修饰,避免被误改,符合常量的使用规范 final double FEDERAL_TAX_PERCENT = 10.00; final double STATE_TAX_PERCENT = 4.5; final double SOCIAL_SECURITY_PERCENT = 6.2; final double MEDICARE_PERCENT = 1.45; final double PAY_PER_HOUR = 7.25; int HoursPerWeek = 40; double GrossPay = PAY_PER_HOUR * HoursPerWeek; double Federal = GrossPay * FEDERAL_TAX_PERCENT / 100; double State = GrossPay * STATE_TAX_PERCENT / 100; double SocialSecurity= GrossPay * SOCIAL_SECURITY_PERCENT / 100; double Medicare = GrossPay * MEDICARE_PERCENT / 100; double NetPay = GrossPay - Federal - State - SocialSecurity - Medicare; public static void main(String[] args) { // 先实例化NetPay类,得到实例对象 NetPay netPay = new NetPay(); System.out.println("Gross Pay:" + netPay.GrossPay); System.out.println("Net Pay:" + netPay.NetPay); System.out.println(""); System.out.println(""); System.out.println("Deductions"); System.out.println("Federal:" + netPay.Federal); System.out.println("State:" + netPay.State); System.out.println("Social Security:" + netPay.SocialSecurity); System.out.println("Medicare:" + netPay.Medicare); } }
方案2:将所有相关成员变量修改为静态变量(适合单场景一次性计算的场景)
给所有在main方法中需要访问的成员变量加static修饰,让这些变量变成类级别的成员,类加载阶段就会完成初始化,可直接被静态方法访问,修改示例如下:
public class NetPay { // 固定常量加static final修饰,成为类常量,全局唯一节省内存 static final double FEDERAL_TAX_PERCENT = 10.00; static final double STATE_TAX_PERCENT = 4.5; static final double SOCIAL_SECURITY_PERCENT = 6.2; static final double MEDICARE_PERCENT = 1.45; static final double PAY_PER_HOUR = 7.25; static int HoursPerWeek = 40; static double GrossPay = PAY_PER_HOUR * HoursPerWeek; static double Federal = GrossPay * FEDERAL_TAX_PERCENT / 100; static double State = GrossPay * STATE_TAX_PERCENT / 100; static double SocialSecurity= GrossPay * SOCIAL_SECURITY_PERCENT / 100; static double Medicare = GrossPay * MEDICARE_PERCENT / 100; static double NetPay = GrossPay - Federal - State - SocialSecurity - Medicare; public static void main(String[] args) { System.out.println("Gross Pay:" + GrossPay); System.out.println("Net Pay:" + NetPay); System.out.println(""); System.out.println(""); System.out.println("Deductions"); System.out.println("Federal:" + Federal); System.out.println("State:" + State); System.out.println("Social Security:" + SocialSecurity); System.out.println("Medicare:" + Medicare); } }
数据类型优化说明
- 所有固定不变的税率、时薪参数,使用
static final修饰为类常量,类型使用double符合小数计算的精度要求 - 周工时
HoursPerWeek为整数,使用int类型合理 - 薪资、扣款类字段涉及小数计算,统一使用
double类型满足精度要求
内容的提问来源于stack exchange,提问作者张Taddy
相关产品推荐
相关产品推荐

