Java语言程序设计
上QQ阅读APP看书,第一时间看更新

2.2 “员工工资扣税”实例

实例说明

本实例是输入任何一位员工的税前工资,即可计算得出员工工资扣税档次并输出,程序运行结果如图2.2所示。

图2.2 程序输出结果

【实例目的】

(1)学习并掌握常量和变量的概念和使用。

(2)学习并掌握Java的运算符,理解各类运算符的优先顺序。

(3)学习并掌握表达式的计算,能根据程序的实际需要合理选择运算符并使用表达式。

(4)学习并掌握Java语句的特点及使用。

(5)学习并掌握程序开发的一般步骤和方法。

【技术要点】

1)2011年9月1日起调整后,实行的7级超额累计个人所得税税率如下所示。

级数  全月应纳税所得额  税率/%  速算扣除数/元

1  不超过1500元的  3  0

2  超过1500元至4500元的部分  10  105

3  超过4500元至9000元的部分  20  555

4  超过9000元至35000元的部分  25  1005

5  超过35000元至55000元的部分  30  2755

6  超过55000元至80000元的部分  35  5505

7  超过80000元的部分  45  13505

2)个人所得税计算方法

(1)全月应纳税所得额=月薪金收入总额−3500−个人支付的社保和公积金费用;

如案例中相应程序段如下:

(2)全月应纳税额=全月应纳税所得额×适用税率-速算扣除数;

如案例中相应程序段如下:

//根据公式全月应纳税额=全月应纳税所得额×适用税率-速算扣除数,计算应纳税额

taxPay=allTaxableIncome*taxRate-quickDeduction;

【相关知识及注意事项】

2.2.1 常量

1.常量的概念

常量是指直接用在程序中、在程序运行过程中固定不变的量。变量是指在程序运行过程中其值可以变化的量。

2.常量的类型

Java语言中的常量值是用数值或字符串表示的,包括如下几种类型:

1)整型常量

整型常量又称整数,在Java中,整数也可以用4种数制来表示。

(1)二进制整数

例如0b101、−0B101,其中,每个数字位必须是0或1。Java SE7开始,程序中凡出现以0b(或0B)开头的数字序列,一律作为二进制数处理。

(2)八进制整数

例如,010、027,其中,每个数字位必须是0~7。程序中凡出现以数字0开头的数字序列,一律作为八进制数处理。

(3)十进制整数

例如,250、−12,其中,每个数字位必须是0~9。

(4)十六进制整数

例如,0x80、0x1a,0X80、0X1A,其中,每个数字位必须是0~9、a~f或A~F。程序中凡出现以0x(或0X)开头的数字序列,一律作为十六进制数处理。

Java的默认整型常量类型为int类型,用4个字节表示。如果要表示long类型的整型常量,需要在整数后加上后续L或l,表示长整型,它在机器中占64位。例如,1234567L,987654320l等。

2)浮点常量

浮点常量是可以含有小数部分的数值常量。根据占用内存长度的不同,可以分为单精度浮点常量和双精度浮点常量两种。如果要表示单精度浮点常量,用F或f表示,如本案例中的税率0.03f;双精度浮点常量占64位内存空间,可以在小数后面加后缀D或d进行表示,也可以不加后缀,因为默认的小数就是双精度。

浮点常量又称实数,它可以用两种形式表示,即小数形式和指数形式。

(1)小数形式

小数形式是由数字和小数点组成的(注意:必须要有小数点)。例如:0.123、.123、123.、0.0都是以十进制小数形式的合法实数。

(2)指数形式

指数形式又称科学计数法。例如:十进制小数180000.0,用指数形式可表示为1.8e5;而十进制小数0.00123,用指数形式可表示为1.23E-03。这里的字母E表示以10为底的指数,也可以用小写的e表示。采用科学表示法时应注意,字母E或e前后必须要有数字,且E或e后面的指数必须为整数。例如,实数123E4、135.6e-7、.123E8、0e0都是合法的,而E5、3.2e0.5、5E、.e3都是不合法的。

3)字符常量

字符常量是用单引号括起来的一个字符。其中,单引号是字符常量的定界符。例如,'a'、'A'、'@'、';'、'6'等都是合法的字符常量,其中,'a'和'A'是不同的字符常量。

Java还允许使用一些特殊形式的字符常量,它是以一个反斜杠“\”开头的字符序列,称为转义字符,意思是使反斜杠“\”后面的字符不再有原来的含义。例如,前面例题中出现的字符'\n',不是表示字符反斜杠“\”和“n”,而是表示换行。Java语言中常见的转义字符见表2.3。

表2.3 转义字符及其功能

注意:以“\”开头的转义字符,仅代表单个字符,而不代表多个字符。

4)字符串常量

与C语言相同,Java语言的字符串常量是用双引号(" ")括起来的一串字符,如"A"、"Hello Java!!"。不同的是,Java语言的字符串常量是作为String类的一个对象来处理的,而不是一个数据。例如,案例中输出员工扣税情况时需要的“员工编号”定义如下:

String no="10000";  //员工编号

后面将详细介绍String类。

5)布尔型常量

布尔数据类型用于表不两个逻辑状态之一的值:true(真)和false(假),在控制语句中常用到它。Java规定不可将布尔型看成整型值,它们不对应于任何整数值。

2.2.2 变量

1.变量的定义

变量是指运行过程中值能够改变的量。定义变量的一般语法格式为:

[变量修饰符] 变量类型说明符 变量名 列表[=初值];

(1)变量名是程序引用变量的手段。Java语言中的变量名要符合标识符的命名规则。标识符是能被编译器识别而提供的、在程序中唯一的名字,可以是任意长度。如上述例子中的level、quickDeduction、taxRate和taxPay都是Java语言中合法的标识符。此外,变量的名称应具有一定的含义,以增加程序的可读性。

(2)变量修饰符是可选项,说明了变量的访问权限和某些规则,变量修饰符将在第二篇中详细讲解。

(3)变量类型说明符确定了变量的取值范围以及对变量所能进行的操作,关于变量类型可以是本章中所提到的任何数据类型。

(4)变量列表由一个或多个变量名组成。当要定义多个变量时,各变量之间用逗号分隔。

(5)初值是可选项,变量可以在定义的同时赋初值,也可以先定义,在后续程序中赋初值。

例如,案例中相关变量的定义如下:

2.变量的作用域

变量的作用域指明了可访问该变量的代码范围,声明一个变量的同时也就指明了变量的作用域。在一个确定的域中,变量名应该是唯一的。

按作用域来分,变量可以分为以下几种:

(1)局部变量:局部变量在方法或方法的一个块代码中声明,它的作用域为它所在的代码块(整个方法或方法中的某块代码)。

(2)方法参数:方法参数传递给方法,它的作用域就是这个方法。

(3)异常处理参数:异常处理参数传递给异常处理代码,它的作用域就是异常处理部分。

(4)类(成员)变量:在类中声明,而不是在类的某个方法中声明,它的作用域是整个类。

3.变量的初始化

初始化变量的常用形式有6种,具体操作方法如下:

(1)初始化一个变量,其格式为:

变量类型 变量名;

变量名=数据;

例如,本案例中对社保和公积金额度变量sg的定义和初始化,如下所示。

float grossPay;  //税前工资

grossPay=input.nextFloat();

(2)一行定义多个同样类型的变量再分别赋初值,其格式为:

变量类型 变量名l,变量名2,…,变量名n;

变量名l=数据;变量名2=数据;…;变量名n=数据;

例如,本案例中对社保变量sb和公积金变量gjj的定义和初始化,如下所示。

(3)定义和赋初值合并使用,其格式为:

变量类型 变量名=数据;

例如,本案例中对税率变量taxRate的定义和初始化,如下所示。

float taxRate=0;  //税率

(4)一次定义多个同样类型的变量并且赋初值,其格式为:

变量类型 变量名l=数据,变量名2=数据,…,变量名n=数据;

(5)一次给多个变量赋同样的初值,其格式为:

变量名1=变量名2=…=变量名n=数据;

例如,本案例中对税率级别变量level和速扣除数变量quickDeduction的初始化,如下所示。

level=quickDeduction=0;

(6)引用变量的赋值格式如下:

引用数据类型 变量名=new 引用数据类型();

说明:方法体中的变量必须初始化后才能使用,而类中的成员变量可自动进行初始化。关于类变量将在第二篇进行详细讲解。

2.2.3 运算符和表达式

1.运算符

对各种类型的数据进行加工的过程称为运算,表示各种不同运算的符号称为运算符。

1)运算符的分类

Java语言的运算符按参与运算的数据(即操作数)的数目分为:单目运算符(如++、−−等)、双目运算符(如+、−、*、/等)、三目运算符(?:)。按功能可划分为:算术运算符、赋值运算符、关系运算符、逻辑运算符、条件运算符、位运算符、逗号运算符等。

(1)算术运算符

算术运算符用于各类数值运算。包括正号(+)、负号(-)、加(+)、减(-)、乘(*)、除(/)、求余(或称模运算,%)、自增(++)和自减(--)9种。

● 自增运算符的作用是使操作数完成自动加1的运算。例如,++a表示在使用变量a前,完成变量n的加l运算;a++表示在使用变量a后,完成变量a的加1运算。

● 自减运算符的作用是使操作数完成自动减l的运算。例如,--a表示在使用变量a前,完成变量a的减1运算;a--表示在使用变量a后,完成交虽a的减1运算。

● 求余运算是一个双目运算符,两个操作数都只能是整数。

(2)赋值运算符

赋值运算符是一个双目运算符,作用是利用“=”号,将表达式右例的数据传递给左侧的操作数。赋值运算符可分为简单赋值(=)、复合算术赋值(+=、-=、*=、/=,%=)和复合位运算赋值(&=、|=、^=、>>=、<<=、>>>=)3类,共12种。

(3)逗号运算符

逗号运算符用于把若干表达式组合成一个表达式。在C和C++里,逗号不仅作为函数自变量列表的分隔符使用,也作为进行后续计算的一个运算符使用。在Java里需要用到逗号的唯一场所就是for循环(for循环在本章第3节将会进行详细讲解)。

(4)关系运算符

Java语言提供了6种关系运算符:大于(>)、小于(<)、等于(==)、大于等于(>=)、小于等于(<=)和不等于(!=)。

关系表达式的运行结果是—个布尔类型值:true和false。如果关系成立,表达式的值为true;关系不成立,表达式的值为false。

例如,本案例中对税率级别进行判定时,若allTaxableIncome=1000,判定表达式allTaxableIncome<=1500的值为true;若allTaxableIncome=1600,判定表达式allTaxableIncome<=1500的值为false;

(5)逻辑运算符

逻辑运算与关系运算的关系十分密切,关系运算的运算结果是布尔型的运算,而逻辑运算的操作数和运算结果都是布尔型的运算。

逻辑运算符有6种,分别为!(非)、&(非简洁与)、|(非简洁或)、^(异或)、&&(简洁与)、||(简洁或),其中,!是单目运算符。

Java语言提供两种与和或的运算符:

①&&、||:逻辑表达式求值过程中,先求或运算左边表达式的值,对于或运算如果为true,则整个逻辑表达式的结果就是true,从而不再对右边的表达式进行运算;同样对于与运算,如果与运算左边表达式的值为false,则整个逻辑表达式的结果就是false,右边的表达式就不需再进行运算了。

②&、|:利用&、|做运算时,运算符两边的表达式都要被判断,即不管第一个表达式的结果能否推测出整个逻辑表达式的结果,都要对第二个表达式进行运算。

(6)条件运算符

条件运算符是三目运算符,相当于条件判断,其格式为:

表达式? 语句1:语句2;

其中表达式的值是布尔类型,当表达式的值为true时执行语句1,否则执行语句2。要求语句1和语句2返回的数据类型必须相同,并且不能无返回值。

例如:

int x=5;

int a=(x>3)?5:3;

则a的值为5。如果x=2,则a的值为3。

(7)位运算符

位运算符是用来对整型数据的二进制位进行测试、置位或移位处理。位运算符包括位与(&)、位或(|)、位非(~)、位异或(^)、左移(<<)、右移(>>)和无符号右移(>>>)7种,按功能划分为位逻辑运算符和位移位运算符。

①位逻辑运算符

位逻辑运算符是对操作数的每位上进行相应的逻辑运算。位逻辑运算符共4种,其中~(非)为单目运算符,其余3种&(与)、|(或)、^(异或)为双目运算符,其逻辑运算规则同逻辑运算符。

表2.4列出了Java语言的位逻辑运算符。表2.5列出了位逻辑运算符运算规则。

表2.4 位逻辑运算符

表2.5 位逻辑运算符运算规则

上述每一种位逻辑运算符根据其运算规则都有一定的用途:

● 逻辑与用途是清零:如果将—个存储单元清零,即使其全部二进制位为0,可以找一个新数,原来数为1的位,新数中相应位为0,原来数中为0的位,新数相应位可以为0或1。再对两者进行&运算,就可以将其清零。

● 逻辑或的用途是置1:如果将一个存储单元置1,即使其全部二进制位为1,可以找一个新数,原来数为0的位,新数中相应位为1,原来数中为1的位,新数相应位可以为0或1。再对两者进行运算,就可以将其置1。

● 逻辑异或的用途有两种:一种是位特定位翻转,即将欲翻转的位与1进行异或运算;另一种是使特定位保留原值,即将欲翻转的位与0进行异或运算。

②位移位运算符

位移位运算是针对整型数的二进制进行。这里的二进制并不是该数本身的二进制码,而是要进行编码。常用的编码有:原码、反码、补码。

移位运算符是把操作数的第一位向左或向右移动一定的位数。Java中的位运算符如表2.6所列。

表2.6 位移位运算符

对于位的移位运算符要进行如下说明:

①左移运算中左移一位相当于乘以2,右移一位相当于除以2。用移位运算实现乘除比算术中的乘除法快。

②>>称为带符号位右移,进行右移运算时,最高位为0,则左边补0,最高位为1,则左边补1,即符号位不变。假设操作数按字节类型存储。

③>>>称为无符号位右移,进行右移运算时,左端出现的空位用0补。假设操作数按字节存储。

注意:位运算中的操作数必须是二进制数,而逻辑运算中的操作数必须是true和false。

(8)其他特殊运算符

包括括号()、下标[]、对象运算符instanceof和内存分配运算符new等。

2)运算符的优先级和结合性

与运算符相关的两个概念分别是优先级和结合性。在对表达式求值时,先按运算符的优先级别由高至低依次执行,如先乘除后加减,而在一个运算数两侧的运算符优先级相同时,则按运算符的结合性所规定的结合方向处理。

Java语言中各运算符的结合性分为两种,即自左向右和自右向左。例如:算术运算符的结合性是自左向右,赋值运算符的结合性是自右向左。

2.表达式

(1)表达式的定义

运算符与一定的运算量按照相应的语法规则结合就组成了表达式,从而完成相应的运算。其中,运算量可以为常量、变量、函数调用,甚至可以为表达式。表达式求值按运算符的优先级和结合性所规定的顺序进行。

例如,税率的判定条件是:超过1500元至4500元的部分,税率为10%。案例中判断allTaxableIncome是满足该条件的表达式如下:

(allTaxableIncome>1500 &&allTaxableIncome<=4500)

(2)表达式的分类

表达式的类型由运算以及参与运算的操作数的类型决定,可以是简单类型,也可以是复合类型:

布尔型表达式:allTaxableIncome<=1500

整型表达式:num1+num2

2.2.4 语句

Java语句用于向计算机系统发出操作指令,主要可以分为以下几类:

1.表达式语句

表达式语句是由表达式在其最后加一个语句结束标志分号构成。格式如下:

表达式;

例如:本案例对缴纳税额进行计算的时候,

taxPay=allTaxableIncome*taxRate-quickDeduction

是一个赋值表达式,而

taxPay=allTaxableIncome*taxRate-quickDeduction;

是一个赋值语句。

2.方法调用语句

由一次方法调用加一个分号构成的语句。

例如,本案例中对扣税信息进行输出时的输出语句。

3.空语句

只有一个分号的语句,什么都不做。有时用在循环语句中的循环体,用来实现空循环。下面是一个空语句:

4.复合语句

可以用{}把一些语句括起来构成复合语句。

例如本案例中对扣税级别判定后各变量的值的确定就是一个复合语句:

5.控制语句

控制语句主要完成程序控制功能。Java提供了8种控制语句:if−else语句、switch语句、while语句、do−while语句、for语句、break语句、continue语句和return语句。这些语句将在下一节中详细讲解。

【代码及分析】

程序解释及常见问题如下:

(1)语句“gjj=(float)(grossPay*0.05);”在进行赋值的同时还进行了数据类型的转换。需注意的是:数据类型的转换有两种形式:系统自动转换和强制转换。在本条语句中,先是在进行乘法运算的表达式“grossPay*0.05”中进行系统自动类型转换,接着在赋值运算过程中进行了强制类型转换(float)(grossPay*0.05)。

(2)在用关系表达式表示数学的不等式时要注意两者的区别,要在以后的过程中习惯程序设计语言中的关系表达式的表示形式。如要表达1500<allTaxableIncome<4500这个数学表达式,程序设计语言要用&&运算分段表达,即allTaxableIncome>1500 &&allTaxableIncome<=4500。

【应用扩展】

程序给出的计算应缴纳税额的方法,该方法完善后可形成一个“个人扣税计算器”;另外,还可以进行反推计算,已知某人缴纳的税额,可推出其税前所得。