Bootstrap

02.变量和运算符

一.单元概述

        本小节开始,我们首先学习Java语言中的基本概念变量,声明变量时的数据类型、变量的命名规则、数据类型之间的转换原则以及运算符的使用。学习完本章之后我们应该能够了解Java的基本语法,掌握基本语法的编写,为后续程序编写奠定坚实的基础。

1.1 Java程序结构

        程序是由程序块组成的,所谓程序块,指的是使用一对 { }包括的若干行代码的总称。程序块是由变量、数据类型、运算符和控制语句共同组成的。

        其中数据类型确定要存储在内存中的数据的类型;变量是存储数据的基本单元;运算符是一个符号,用于操作一个或多个参数以得出结果;程序是按顺序执行的,控制流语句允许改变程序执行顺序。

1.2 标识符、关键字和保留字
1.2.1 标识符

在Java语言中,通过标识符来表示一些元素的名字,比如变量名、类名、方法名和包名等。Java中的标识符要符合下面的规则:

        1. 标识符必须以字母、下划线(_)、数字或美元($)组成;

        2. 标识符必须由字母、下划线(_)或美元($)开头,不能由数字开头;

        3. 标识符不能是关键字或者保留字;

        4. 标识符中不能有空格;

        5. 标识符没有长度限制。

        例如,A_123,$abc,length都是合法的标识符,而1a,s+g就是非法的标识符。

在生产环节中,各个公司对标识符有特定的要求,也就是说在满足是标识符的基础之上又增加代码的可读性和规范性的要求,提出了很多规范。

        提示:

        Java区分大小写,因此area和Area是两个不同的标识符;

        为提高程序的可读性,建议使用有意义的命名标识符,如area,length等

1.2.2 关键字和保留字

        下表是Java中的关键字和保留字,关键字是对Java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等;保留字是为Java预留的关键字,虽然现在没有作为关键字,但在以后的升级版本中有可能作为关键字,关键字和保留字如下表所示。

abstract

continue

goto

null

switch

assert

default

if

package

synchronized

boolean

do

implements

private

this

break

double

import

protected

throw

byte

else

instanceof

public

throws

case

extends

int

return

transient

catch

final

interface

short

try

char

finally

long

static

void

class

float

native

strictfp

volatile

const

for

new

super

while

        //不要害怕,不用背,以后用着用着就全知道了。

1.3 变量

        变量(variable)是用来存储数据的一块存储区域,在程序运行中它的值可以发生变化。变量可以存放一种数据类型的值,Java程序在运行加载时会根据变量的不同数据类型来分配不同的内存空间,变量的数据类型在声明时指定。

        变量是指在程序的运行过程中随时可以发生变化的量,作用是:

        1.变量是程序中数据的临时存放场所

        2.保存程序运行时用户输入的数据

        3.特定的运算结果等

1.3.1 变量的声明

        一个变量只有在声明后才有效,声明的作用就是确定该变量要存储的数据类型。声明变量的语法格式如下:

        数据类型 变量名,

                如: int age;

        如果要同时声明多个相同数据类型的变量,可以如下写:

        数据类型 变量名1,变量名2;

        代码举例如下:

                int number, max;

        变量在声明后,不能直接访问,只有被赋值的变量才能够被访问,否则就会出现运行错误。

1.3.2 变量的赋值

        第一次给变量赋值叫"初始化"。使用等号"="来进行赋值,语法如下:

        变量名 = 数据值;

        例如:

                int number;

                number = 1000;

        也可以把变量的声明和初始化合用一个语句实现出来,例如上面两行代码就可以改写成一行代码:

int number = 1000;

        每个已经声明了数据类型的存储变量只能存储对应类型的数据。如下代码是正确的:

int num = 100;
double pi = 3.14;

class VariableDemo{
    public static void main( String args[]) {
        double salary; //声明变量
        salary = 1500.00; //变量赋初值
        System.out.println(salary); //变量的访问
    }
}

1.3.3 常量

        在程序中往往会存在变量值不需要变化的情况,比如表示圆周率的变量,比如表示黄金分割点的变量,那么这些值不允许发生改变的变量就叫常量。

        在Java中,常量用关键字final来表示(在后面章节会详细讲解),它也是有数据类型的,语法如下:

        final 数据类型 常量名 = 初始值;

提示:

        1.常量在声明的时候必须初始化;

        2.常量在初始化后值不能再更改,否则会引起错误。

        例如:

final double PI = 3.14;

1.4 基本数据类型

        在现实生活中,数据是以多种形式存在的,比如数字、文字、图形、声音等形式,所有这些能够被输入到计算机并且可以被计算机处理的内容都被称为数据。在计算机的世界中,我们使用数据类型来描述这些不同的数据。

        每个数据类型都有取值范围,编译器会对每种数据类型分配相应大小的存储空间。下面我们来详细介绍一下这8种基础数据类型 

1.4.1 数值数据类型

1.整型

        Java有4种整形数据类型,下表列出了整型的类型及值域范围:

byte

字节型

1个字节(8位二进制)

-128 到 127

short

短整型

2个字节(16位二进制)

-2^15 到 2^15-1

int

整型

4个字节(32位二进制)

-2^31到 2^31-1

long

长整型

8个字节(64位二进制)

-2^63到 2^63-1

        Java语言的整型常量默认为int型,声明long型后面需加上l或者L,否则会出错。

        Java中整型的四种表示形式:

                1.十进制整数:0 ~ 9,注:第一位不能是0

                2.十六进制数:0 ~ 9 A ~ F, 注:必须以0x或0X开头,例如: 0X8A 0x12

                3.八进制整数:0 ~ 7,注:必须以0开头,例如: 0123 012

                4.二进制整数:0~1,注:必须以0B开头(在java1.7及以上版本可用),例如: 0B1010

2.浮点型

        与整数类型相似,Java浮点数类型有固定的表示范围和字段长度,不受平台影响,浮点数据类型如下表:

        浮点型数据类型表

类型

说明

占空间大小

值域

float

单精度浮点型

4个字节,精度约7位

-3.403E38 ~ 3.403E38

double

双精度浮点型

8个字节,精度约为17位

-1.798E308 ~ 1.798E308

        Java浮点数类型有两种表示形式,分别是十进制形式和科学计数法形式,具体表示方式如下:

       十进制数形式,例如:3.14 314.0 0.314

       科学计数法形式,如:3.14e2 3.14E-1

        Java浮点型常量默认为double型,如要声明一个常量为float型,则需在数字后面加f或F,如:

double d = 12345.6;
float f = 12.3F;

提示:

        1. 带小数的数据默认是double型而非float型的;

        2. 定义float型数据需要后面紧跟"f"或"F"来表示,比如float f = 2.1f;

        3. 定义长整型数据,可以后面紧跟"l"或"L"来表示。

1.4.2 字符数据类型

        字符数据类型用于存放单个字符,每个字符占用2个字节(16位二进制)的内存空间。一个字符型数据由单引号括起来,使用"char"关键字来说明数据类型,如下:

char letter = 'a';

         字符及其含义

字符含义
'a'字母a
'中'汉字中
'\n'转义字符表示换行
'\u????'特定的Unicode字符,用\u+四个确切的十六位数字代替
'\u03A6'Unicode字符表示希腊字符Φ

        字符类型是一个16位无符号整数,Java中字符类型的值是对应字符的编码, 是unicode编码,其中,英文部分的值与ascII编码一致。char是定长编码, 所有的字符都是16位。例如:

        'A' 对应的编码是0x0041

        '中'对用的编码是 0x4e2d

        char类型在编码中: '0'~'9', 'a'~'z', 'A'~'Z'都是连续编码的,'0'与'\u0000'不是同一个字符,字符编码的最小值为0, 最大值是65535 ,也就是2^16-1,使用时要注意字符字面量使用单引号为定界符号。

提示:

        1. 字符型只表示一个字符,不能表示多个字符,比如'abc'是错的;

        2.字符型只能用单引号(')括起来,用双引号(")括起来的不是字符,而是字符串(String),比如"a"表示的不是char型字符而是String型字符串。

        Java还允许使用转义字符来表示特殊字符。转义字符用斜杠"\"打头,后面跟一个字符。

常见的转义字符如下表。

常见转义字符

名称

转义字符

说明

退格键

\b

表示一次退格

Tab键

\t

表示一个Tab空格

换行符

\n

表示换行

回车键

\r

表示回车

斜杠

\\

表示斜杠

单引号

\'

表示单引号

双引号

\"

表示双引号

        转义字符用在一些特殊字符的表示上,如下代码:

        例 转义字符的用法

public class EscapeCharDemo {
    public static void main(String[] args) {
        System.out.println("escape\bchar");
        System.out.println("escape\tchar");
        System.out.println("escape\rchar");
        System.out.println("escape\nchar");
        System.out.println("\\我在斜线里\\");
        System.out.println("\'我在单引号里\'");
        System.out.println("我没有单引号");
        System.out.println("\"我在双引号里\"");
        System.out.println("我没有双引号");
    }
}

1.4.3 布尔数据类型

        布尔数据类型由关键字boolean来表示,布尔型数据的值域只有两个值:true和false。例如,下面两行代码:

boolean isOK = true;
boolean isFirst = false;

提示:

        1. true和false都是小写,True、TRUE、False、FALSE都不是布尔型数据的值;

        2. 布尔型数据不能用数字0和1来表示真假,只能用true和false;

        3. 布尔型数据默认值是false。

例: 布尔数据类型

boolean flag;
flag = true;

1.5 数据类型转换

        在上面的代码例子中,我们已经看到会有数据类型与变量声明的类型不匹配的情况发生。Java是强类型语言,要求赋值或传递时数据类型必须匹配,我们可以利用Java提供的数据类型的转换来消除这种错误。

        Java提供了两种数据类型的转换方式:自动转换和强制转换。

1.5.1 自动数据类型转换

        自动数据类型转换也称之为隐式类型转换,我们在数值数据类型中了解到,不同类型的数据会占用不同大小的存储空间,那么数据类型自动转换的原则就是:小空间的数据类型可以自动转换成大空间的数据类型,也就是说低精度的数据可以升级成高精度的数据,反之不行,我们可以理解成高精度的数据转换成低精度的数据会失去数据的精度,所以能这样转换。

        byte,short,char 可以向 int 类型转换 int 可以向 long 类型转换 long 可以向 float 类型转换 float 可以向 double 类型转换。

2.5.2 强制数据类型转换

        强制数据类型转换也称之为显式类型转换,既然有些数据类型不能互相自动进行转换,那么Java提供了强制转换的方法,强制转换的语法就是用圆括号括起你要转换成的目的数据类型:

        变量=(目标类型)值;

例如:

byte a;
int b;
a = (byte) b;
int i = (int)2.8;
float f = (float)5.2;
class TestConvert {
    public static void main(String arg[]) {
        /*自动类型转换*/
        int i1 = 12;
        int i2 = 45;
        double d1 = (i1 + i2) * 1.0;//系统将转换为double型运算
        System.out.println(d1);
        /*自动类型转换*/
        float f3 = 12.3f;//必须加f
        long l1 = 12300;
        long l2 = 300000000000L;//必须加l
        float f = l1 + l2 + f3;//系统将转换为float型计算
        System.out.println(f);
        byte m1=1;
        byte m2=3;
        byte m = (byte)(m1+m2);
        /*强制类型转换*/
        long l = (long)f;//强制转换会舍去小数部分(不是四舍五入)
        System.out.println(l);
        /*强制类型转换*/
        byte b1 = 67;
        byte b2 = 89;
        byte b3 = (byte)(b1 + b2);//系统将转换为int型运算,需要强制转换符
        System.out.println(b3);
    }
}

提示:

        1. boolean型数据不能和其他基本数据类型进行转换;

        2. char型和int型数据可以互换;

        3. byte、short、char之间不会相互转换,它们三者在计算时首先会转换为int类型;

        4. 在强制类型转换过程中,源类型的值可能大于目标类型,因此可能造成精度降低或溢出,使用时需注意。

1.6 运算符

        在程序设计中经常会做一些运算,比如算术运算、关系运算和逻辑运算。Java语言中也使用了一些常见的运算符和表达式来进行运算,下面我们就介绍这些运算符和表达式。

2.6.1 算术运算符和表达式

        算术运算是一种常见的运算,主要是对数值型数据进行加减乘除等运算,Java的算术运算符如下表:

算术运算符

运算符

名称

备注

+

加运算符

-

减运算符

*

乘运算符

/

除运算符

若是两个整数相除,只保留整数部分

%

取模(取余)运算符

被除数为正数结果都为正,被除数为负数结果都为负

++

自增

++变量名:变量在参与其他操作前先将自己加1;
变量名++:先用原来的值参与其他操作后,再将自己加1

--

自减

算法同++

+

字符串连接

当操作数中只要有一个是String类型,系统会自动将另一个操作数转换成字符串类型,然后进行连接

        例 比较前置++与后置++的不同。

public class SelfplusOperatorDemo1 {
    public static void main(String[] args) {
        int i = 0;
        int a = i++;
        System.out.println(a + ", " + i);// 0,1
        a = ++i;
        System.out.println(a + ", " + i);// 2,2
        i = i++;
        System.out.println(i);// 2
        i = 0;
        System.out.println(i++ % 3);// 0
        System.out.println(i++ % 3);// 1
        System.out.println(i++ % 3);// 2
        System.out.println(i++ % 3);// 0
        System.out.println(i++ % 3);// 1
        System.out.println(i++ % 3);// 2
        System.out.println(i++ % 3);// 0
    }
}

        例 比较前置++与后置++的不同。

public class SelfplusOperatorDemo2{
    public static void main(String args[]){
        int x1 = 3, y1 = 5;
        int x2 = 3, y2 = 5;
        int r1, r2;
        r1 = x1++ + x1*y1;
        r2 = ++x2 + x2*y2;
        System.out.println("x1="+x1+" y1="+y1+" r1="+r1);
        System.out.println("x2="+x2+" y2="+y2+" r2="+r2);
    }
}

        字符串连接运算符

        在Java中,字符串连接运算符使用"+"运算符,但此时与算术运算符中的加法运算符"+"的意义是不同的。字符串连接运算符,能够将多个字符串合并到一起生成一个新的字符串。

        例 使用字符串连接符。

public class StringDemo{
    public static void main(String args[]){
        char c = 'a';
        String s = "hello";
        int i = 100;
        float f = 2.15f;
        double d = 5.7;
        boolean b = true;
        System.out.println("c=" + c);
        System.out.println("s=" + s);
        System.out.println("i=" + i);
        System.out.println("f=" + f);
        System.out.println("d=" + d);
        System.out.println("b=" + b);
    }
}

        例 使用字符串连接符

public static void main(String[] args) {
		// TODO Auto-generated method stub
		char c='a';
		String s = "hello";
		int i=100;
		float f=2.5f;
		
		System.out.println(i+f+c+s);
		
		System.out.println(i+f+s+c);
		
		System.out.println(c+s+i+f);
		
		System.out.println(c+s+(i+f));

	}

1.6.2 赋值运算符和表达式

运算符

名称

例子

说明

=

赋值运算符

i=8

8赋值给i

+=

加简捷赋值运算符

i+=8

同i=i+8

-=

减简捷赋值运算符

i-=8

同i=i-8

*=

乘简捷赋值运算符

i*=8

同i=i*8

/=

除简捷赋值运算符

i/=8

同i=i/8

%=

取模简捷赋值运算符

i%=8

同i=i%8

public static void main(String[] args) {
		// TODO Auto-generated method stub
		int i = 10;
		i+=8;//18
		System.out.println("i="+i);
		
		i-=8;//10
		System.out.println("i="+i);
	
		i*=8;//	80
		System.out.println("i="+i);
		
		i/=8;//10
		System.out.println("i="+i);
		
		i%=8;//2
		System.out.println("i="+i);
		
	}
1.6.3 关系运算符和表达式

        关系运算又叫比较运算,用来对两个操作数进行大小、等于的关系比较,下表列出了关系运算符。

        关系运算符

运算符

名称

样例

结果说明

>

大于

1>2

false

>=

大于等于

1>=2

false

<

小于

1<2

true

<=

小于等于

1<=2

true

==

等于

1==2

false

!=

不等于

1!=2

true

        关系表达式用于进行关系比较,关系表达式的值都是布尔型的,例如下面代码:

int i = 10;
int j = 16;
boolean smalli = i<j;
boolean equal = i==j;
boolean bigi = i>j;

提示:

        1. 关系表达式的结果都是布尔值,true或false;

        2. 比较相等的是双等号"==",不是一个等号"=",一个等号"="只能用来赋值。

1.6.4 逻辑运算符和表达式

        逻辑运算又叫布尔运算,包括四个运算符,分别是&&、||、!和^,用来进行与、或、非和异或的逻辑运算。逻辑运算的操作数和结果都是布尔类型的值。下表列出了逻辑运算符。

        逻辑运算符

运算符

名称

运算规则

&&

与运算符

逻辑与

运算符左右两端的操作数都为true,表达式结果才为true,其它情况表达式结果为false

| |

或运算符

逻辑或

运算符左右两端的操作数都为false,表达式结果才为false,其它情况表达式结果为true

!

非运算符

逻辑取反

操作数为true,结果为false;操作数为false,结果为true

        例如下面代码:

public static void main(String[] args) {
		// TODO Auto-generated method stub
		boolean x = true;
		boolean y = false;
		
		System.out.println(x&&y);//false
		System.out.println(x||y);//true
		System.out.println(!x);//false
		System.out.println(x^y);//亦或,相同为假,不同为真				
	 }

        短路与 vs 非短路与

public static void main(String[] args) {
		//短路与&& vs 非短路与&
		int a =10;
		int b =20;
		int c =30;
		
		//boolean flag = a>b && ++b>c;//左边为假,右边短路了
		//System.out.println(flag);//false
		//System.out.println(b);//20
		
		boolean flag = a>b & ++b>c;//右边不短路
		System.out.println(flag);//false
		System.out.println(b);//21			

	}

        短路或 vs 非短路或

public static void main(String[] args) {
		//短路或|| vs 非短路|		
		int a =10;
		int b =20;
		int c =30;
		
		//boolean flag = a<b||++b>c;//左边为真,右边短路了
		//System.out.println(flag);//true
		//System.out.println(b);//20
		
		boolean flag = a<b|++b>c;//右边不短路
		System.out.println(flag);//true
		System.out.println(b);//21	

	}
1.6.5 三目条件运算符

        三目条件运算符的语法为:

                表达式1 ? 表达式2 : 表达式3

        如果表达式1为真,取表达式2的值,否则取表达式3的值

        举例如下:

int a=3, b=6;
int x = a>b? a:b;

        那么计算结果就是x=6。

        在三目条件运算中,表达式1和表达式2的值可以是任意一种基本数据类型。

        例 三目运算符

public static void main(String[] args) {
		// 三目条件运算符		
		int a=10;
		int b=20;
		
		boolean flag = a<b?true:false;	
		char c = a<b?'真':'假';	
		String ret = a<b?"正确":"错误";
		int x = a<b?1:0;		
		double y = a<b?1.0:2.0;

	}
1.6.6 运算符的优先级

        表达式通常由多个运算符组成。优先级的规则决定每个运算符在任何给定表达式中的计算顺序。表达式是按照从左到右运算符的优先级来进行运算的,正因为这种优先级的限制,才保证了每个表达式每次运算的结果都一样。

        按操作数多少划分

                一元操作符 > 二元操作符 > 三元操作符

        按运算类型划分

                算术运算符 > 关系运算符 > 逻辑运算符 > 赋值运算符

        尽量多的使用括号,括号优先级别最高,使用括号也可保证在不确定优先级的情况下,更好地控制语句的执行顺序。

        运算符优先级

类型转换
++、--
*、\、%
+、-
>、>=、<、<=
==、!=
&
|
&&
||
=、+=、-=、*=、/=

1.7 表达式

        表达式是符合一定语法规则的运算符和运算数的序列。按照使用的运算符和运算结果的不同可以分为:

        1.算术表达式

                例如:(x+y-12)*100

        2.关系表达式

                例如:x>y, x>=y, x!=y, x==y

        3.逻辑表达式

                例如:x&&y, x||y||z, (!x)&&(!y)

        4.赋值表达式

                例如:x=y, x+=y

        关于表达式,有下面几个概念需要介绍。

        1.表达式的值:对表达式中操作数进行运算得到的结果称为表达式的值;

        2.表达式的类型:表达式值的数据类型即为表达式的类型;

        3.表达式的运算顺序:应按照运算符的优先级从高到低的顺序进行,优先级相同的运算符按照事先约定的结合方向进行,具体参考上一小节的介绍。

;