Java - 常量可以存储和计算其中的其他变量吗?

Java - Can constants store and calculate other variables within them?

TL;底部DR

我目前正在我的社区学院学习编程 1,我刚刚收到了关于我几周前提交的实验室的反馈。据说有一个地方我弄错了,但我不确定是不是错了。

一些背景信息:在我们的实验室中,我们应该编写一个程序来收集和计算用户在几个小时内赚取的总收入,然后扣除必要百分比的所得税,花在来自货物、债券等的收入。

实验室的部分说明要求我们 "define values for tax, clothes, school supplies, saving bonds, and parent saving bonds as 'constant' (which was defined as a final at this point in class)."

为了节省space,我决定继续计算常量本身内每一项的总值,而不是只将百分比放在常量中,然后再调用它们。

然而,据我的教授说,这个选择是错误的,因为它没有正确声明我的常量。据推测,唯一应该存储在常量中的是纯数字(即,只是百分比);通过尝试在我的初始化中包含和计算变量,我有效地破坏了我的代码,因为常量将永远锁定第一个计算,并且如果代码是 [=40 则无法计算新的 numbers/variables =] 再次(注意:我刚才 运行 程序通过一个循环来查看这是否正确,并且它仍然正常工作)。

如果我错了,就这样吧,我最终还是学到了一些东西。但如果我不是,我想知道。

这是有问题的代码;你有什么想法?

import javax.swing.JOptionPane;
import java.text.DecimalFormat;

public class Lab2C  
{
    static DecimalFormat form = new DecimalFormat("$#0.00");

public static void main (String[] args) 
    {
        //Declare variables
        String input;
        String output;
        double payRate=0;
        double hourWrk=0;
        double income;

        //"for" loop to collect user input
        for (int count=0;count!=2;count++)
        {
            if (count==0)
                {input=JOptionPane.showInputDialog("Please enter your hourly pay: ");
                 payRate=Double.parseDouble(input);
                }
            else if (count==1)
                {input=JOptionPane.showInputDialog("Please enter your total hours "
                        + "worked for the past month: ");
                 hourWrk=Double.parseDouble(input);
                }
        }

        //Calculate and output final numbers

        income = payRate*hourWrk;

        //Declare the constants
        final double taxed = income-(.14*income);        // <---------
        final double cloth = .1*taxed;                   //The portion of code my
        final double supp = .01*taxed;                   //prof took issue with
        final double myBond = .25*taxed;                 // <---------
        final double prntBond = .5*myBond;

        output = 
                "Total Income (before tax): " + form.format(income) + "\n" +
                "Total Income (after tax): " + form.format(taxed) + "\n" +
                "----------------------------------------" + "\n" +
                "       Funds spent on Clothes: " + form.format(cloth) + "\n" +
                "       Funds spent on School Supplies: " + form.format(supp) + "\n" +
                "       Funds spent on Savings Bonds: " + form.format(myBond) + "\n" +
                "       Parent's funds spent on Savings Bonds: " + form.format(prntBond) + "\n" +
                "----------------------------------------" + "\n" +
                "Total Remaining Funds: " + form.format(taxed-(cloth+supp+myBond+prntBond));

        JOptionPane.showMessageDialog(null, output);
    } 
}

TL;DR - 我如何 initialized/used 我的常量有什么大问题吗?

最好尽可能在字段中使用 final 关键字,以避免多线程问题,并且您将其定义为正常。您的教授意味着您将无法使用 final 关键字重新分配变量。但是在这种情况下你不需要它,所以没关系。

在您当前的应用程序中,您的常量与普通计算变量没有什么不同。实际上,您通过计算应该在您的应用程序中使用的已知的、声明的、pre 计算值来浪费几个 CPU 周期,实际上错过了声明的要点这些值作为常量。

想一想:如果您的所得税突然飙升至 40%,您需要做出哪些改变?如果您的债券跌至 1% 怎么办?常量可帮助您在理想情况下在一个清晰可见的位置进行更改。

理想情况下,您的常量将代表您乘以的百分比。

举个例子:

final double incomeTax = .14;

然后您可以在表达式中使用 incomeTax 来获取实际净额:

double netIncome = income - (incomeTax * income);

我认为你的老师主要是在抱怨你的代码中有文字值。这个想法是你提前定义你的文字常量以避免在你的代码中重复它们。 请参阅以下内容:

static final double INCOME_TAXE_RATE = .14;
static final double CLOTHING_TAXE_RATE = .1;
...
public static main(String[] args)

然后您可以按如下方式使用它们:

double taxed = income-(INCOME_TAXE_RATE * income);      
double cloth = CLOTHING_TAXE_RATE * taxed;              
...

声明文字常量的另一个好处是,如果您需要更新它们,您可以在代码中的一个地方进行更新。这使您的代码更具可读性和可维护性。

另外值得一提的是Java不支持对象不变性的概念,它不直接支持常量。 static 修饰符使变量在不加载 class 实例的情况下可用。 final 修饰符使变量不可更改。这只适用于原始数据类型。 Final 对象,仍然可以修改。

A "constant",在计算机编程术语中,是一个在编译时已知的值,完全基于程序的源代码。该值可以是某些计算的结果,但唯一允许的输入是其他常量。例如,您可以定义一个值为 2 * Math.PI.

的常量

在 Java 中,常量被声明为 class 的 static final 字段——也就是说,在所有方法之外,比如你把 form.

你声明的是不能重新计算的局部变量,不是常量。

现在,您可能想知道我刚才所说的如何与您的程序在 运行 循环时运行良好这一事实兼容。答案在于 Java 的变量范围规则。您的 final 变量在循环体内声明,这意味着它们的范围仅限于该循环体。此外,它仅限于 该循环体的 单次迭代。您的循环 运行 一次,创建所有这些新的局部变量并为它们赋值,完成第一个 运行、 并丢弃这些变量 。当它再次 运行s 时,它不会重复使用相同的变量,而是创建一个全新的批次。这个新批次当然可以像第一个批次一样进行初始化,所以程序会继续工作。