Java学习笔记---操作符
- 使用外部包
- 使用java操作符
- 优先级
- 赋值
- 算术运算符
- 自动递增和递减
- 关系操作符
- 逻辑操作符
- 直接常量
- 按位操作符
- 移位操作符
- 字符串操作符+和+=
- 使用操作符时常犯的错误
- 类型转换操作符
- sizeof
1.使用外部包
添加外部包到环境中:
a.在计算机的CLASSPATH环境变量中添加外部包的绝对路径
b.使用import static 包名*//这样就可以导入该包的所有类或者方法
2.使用java操作符
操作符接受一个或多个参数,并生成一个新值。参数的形式与普通的方法调用不同,但效果是相同的。+,-,*,/,=操作符与其他编程原因类似。
操作符除了生成一个新值,有些操作符也可以改变操作数自身的值。这称为“副作用”。那些能改变其操作数的操作符最普遍的用途就是用来产生副作用;最终产生的值与没有副作用产生的值是一样的。
几乎所有的操作符都只能操作“基本类型”.
例外的操作符:“=”,“==”,“!=”,这些操作符可以操作所有的对象。除此之外,String类支持“+”和“+=”。
3.优先级
最简单的规则:先乘除后加减
若使用括号,则先计算括号里面
对于String类型的元素,“+”意味着字符串链接,且“+”后面若是一个非String类型,则会尝试将其转换为String
4.赋值
“=”取右边的值,复制给左边的变量。右值可以是:任何常数、变量、表达式(它能生成一个值);左值必须是一个明确的、已命名的变量。也就是说,必须有一个物理空间可以存储等号右边的值。
对基本数据类型的赋值很简单,基本类型存储了实际的数值,而并非指向一个对象的引用。所以,在为一个变量进行赋值时,是直接将一个地方的内容复制到了另一个地方。
为对象“赋值”时,真正操作的是对象的引用。倘若讲一个对象赋值给另一个对象,实际是将引用从一个地方复制到另一个地方。假若c=d,那么c和d都指向原本只有d指向的那个对象。
方法调用中的别名问题
别名问题:
当将同一个类的一个对象引用赋值给另一个对象时引用,原来的对象引用会被覆盖,不再被引用的对象会由垃圾回收器自动清理。
在许多编程语言中,方法f()似乎要在他的作用域内复制其参数Letter y的一个副本;但实际上只是传递了一个引用。所以代码行:y.c = 'z';实际上改变的是f()之外的对象。
5.算术操作符
+,-,/,*,%(取模);
整数除法直接去掉小数位,而不是四舍五入。
随机生成数字:
1).首先创建一个Random类的对象,Random rand = new Random(47);如果创建过程中没有传递任何参数,Java会将当前时间作为随机数生成器的种子。这样的话,每次运行都将产生不同的值
47就是提供的随机数种子。
2).方法nextInt()和nextFloat()就可以获得随机产生的数字。(nextLong()和nextDouble()同样有效)
一元减号用于改变数据的符号,一元加无特殊意义,只是为了与一元减相对应。
6.自动递增和递减
前缀递增和前缀递减(++a,--a):先执行运算,再生成值
后缀递增和后缀递减(a++,a--):先生成值,再执行运算
7.关系操作符
关系操作符生成的是一个boolean结果,它们操作的是操作数的值之间的关系。如果关系为真,返回true;如果关系为假,生成false。
关系操作符有:<,>,<=,>=,==,!=
等于和不等于适用于所有的基本数据类型,而其他的比较符不适用于boolean类型。因为boolean只能为true和false。“大于”或“小于”没有实际意义。
测试对象的等价性
关系操作符==和!=也适用于所有对象
这里尽管对象的内容相同,然而对象的引用却是不同的,而==和!=比较的是对象的引用。对于基本数据类型,变量不是引用,而是真实的值,所以对于基本数据类型可以比较数值是否相等。
要比较对象的实际内容需要使用特殊的方法:equals(),这个方法不适用于基本数据类型。基本数据类型直接使用==和!=即可。
8.逻辑操作符
逻辑操作符:“与”(&&),“或”(||),“非”(!)。可根据参数的逻辑关系,生成一个布尔值(true或false)。
“与”,“或”,“非”操作只可应用于布尔值。这与C++有显著区别,Java不允许将一个非布尔值(比如:int(3))当做布尔值(非0)在逻辑表达式中使用。
如果在使用String值的地方使用了布尔值,布尔值会自动转换成适当的文本形式。
可将int类型替换成除布尔值以外的其他任何基本数据类型。
短路
一旦能够明确无误地确定整个表达式的值,就不再计算表达式余下部分了。因此整个逻辑表达式靠后的部分有可能不会被运算。“与”运算时,碰到逻辑表达式为0即可停止,“或”运算时,碰到逻辑表达式为1即可停止,后面的不再计算。
因为test2(2)是false,所以不会再去计算test3(),既可直接得到boolean b的结果。
9.直接常量
直接常量后面的后缀字符标志了它的类型。若为大写(或小写)的L,代表long。
大写(或小写)字母F,代表float;
大写(或小写)字母D,代表double。
十六进制数适用于所有整数数据类型,以前缀0x(或0X),后面跟随0-9或小写(或大写)的a-f来表示。
如果试图将一个变量初始化成超出自身表示范围的值(无论这个值的数值形式如何),编译器都会报告一条错误信息。
char,byte以及short如果超出范围,会自动转换成int型,并提示需要对这次赋值进行“窄化转型”;
short,char:16位;byte:8位;int:32位。
八进制由前缀0以及后续的0~7的数字表示。
使用Integer和Long类的静态方法toBinaryString()可以很容易地实现将相应的类型转换为二进制数。C++和Java都没有二进制的直接表示方法。
指数计数法:
Java采用了一种很不直观的计数法来表示指数,例如:
“e”代表自然对数的基数,大写小写都可以。约等于2.718(Java中的Math.E给出了更精确的double型值),例如1.39xe^(-43)意味着1.39x2.178^(-43)次方,但是在Java中,e表示的是以10为底,所以这个表示的含义是:1.39x10^(-43).
如果编译器能够正确地识别类型,就不必在数值后附加字符,例如语句:long n3 = 200;不存在含混不清的地方,所以200后面的L是用不着的。然而,对于语句:
float f4 = 1e-43f;编译器通常会将指数作为双精度(double)处理,如果没有f, 就会收到出错提示:必须使用类型转换将double转换成float。
10.按位操作符
按位操作符用来操作整数基本数据类型中的单个"比特"(bit),即二进制位。按位操作符会对两个参数中对应的位执行布尔代数运算,并最终生成一个结果。
如果两个输入位都是1,则按位“与”操作符(&)生成一个输出位1;否则生成一个输出位0。
如果两个输入位只要有一个1,则按位“或”操作符(|)生成一个输出位1,否则输出0(两个输入都是0)。
如果输入位的某一个是1,但不全是1,那么按位“异或”操作(^)生成一个输出位0。
按位“非”(~),也称为取反操作符,是一个一元操作符,只对一个操作数进行操作。按位"非"生成与输入位相反的值---若输入0,则输出1;若输入1,则输出0.
按位操作符可与等号(=)联合使用,以便合并运算和赋值:&=、|=、^=都是合法的,由于“~”是一元操作符,所以不可与“=”联合使用。
将布尔类型作为一种单比特对待,可对它执行按位“与”,按位“或”,按位“异或”;但是不能执行按位“非”(大概是为了避免与逻辑NOT混淆);按位操作符具有与逻辑操作符相同的效果,只是它们不会中途“短路”。
11.移位操作符
移位操作符的运算对象是二进制的“位”。移位操作符只可用来处理整数类型。包括左移操作符(<<)和有符号右移操作符(>>)
左移操作符:按照操作符右侧制定的位数将操作符左边的操作数向左移动(低位补0)
有符号右移操作符:按照操作符右侧指定的位数将操作符左边的操作数向右移动;“有符号”右移操作符使用“符号扩展”:若符号为正,则在高位插入0;若符号为负,则在高位插入1
“无符号”右移操作符(>>>):使用“零扩充”:无论正负都在高位插入0。
若对char,byte和short类型的数值进行移位操作,移位前会先将其转换为int类型,并且得到的结果也是一个int型。且只有数值右端的低5位才有用,这样可防止移位超过int型数值所具有位数(2的5次方为32,int只有32位。)
若对一个long类型的数值进行处理,最后得到的结果也是long。此时只会用到数值右端的低6位,以防止移位超过long型数值具有的位数。
"移位"可与"等号"(<<=或>>=或>>>=)组合使用,操作符左边的值会移动由右边的值指定的位数,再将得到的结果赋给左边的变量。
在进行“无符号”右移操作时可能会遇到一个问题:若对byte或short值进行这样的移位运算,得到的可能不是正确的结果。它们会先被转换成int类型,再进行右移操作,然后被截断,赋值给原来的类型,在这种情况下可能会得到-1的结果。
结果:无符号右移操作,在高位添0
结果:无符号右移,在高位添0
结果:先将short转换成int,为什么结果也是32位?
结果:byte先转换为int,为什么结果还是32位?
结果:这个移位操作后没有将值赋回给b,所以其结果是正确的。
12.三元操作符if-else
三元操作符也称为条件操作符,它有三个操作数,最终生成一个值,形式如下:
boolean-exp ? value0 : value1
如果boolean-exp(布尔表达式)的结果为true,就计算value0,否则计算value1,并将结果赋值给操作数。
13.字符串操作符+和+=
这个操作符在Java中有一项特殊用途:连接不同的字符串,这是一个操作符重载
如果表达式以一个字符串起头,那么后续所有操作数都必须是字符串型(编译器会把双引号内的字符序列自动转成字符串)
对于操作符“=”和“+=”,只要前后出现了一个字符串,就会被编译器当成是字符串连接符。
对于语法:""+int(0);显示的是字符串:0,这样做的意义就是免去了调用Integer.toString()的繁琐,即可执行字符串转换的方式。
14.使用操作符时常犯的错误
Java不会自动的将int型数值转换为boolean值。
15.类型转换操作符
类型转换的原意是“模型铸造”,在适当的时候,Java会将一种数据类型自动转换为另一种。
若将一个整数值赋给一个浮点型变量,编译器会将int自动转换成float,类型转换允许显示地进行这种类型的转换。
在不能自动进行转换时,在需要的情况下可以进行强制类型转换。强制类型转换需要将希望得到的数据类型置于圆括号内,放在要进行类型转换的值的左边。
编译器在必要的时候会自动进行int值到long值的提升,但是仍然可以使用程序做这种多余的事情,以提醒自己需要留意。
窄化转换:将能容纳更多信息的数据类型转换成无法容纳那么多信息的类型,比如:long->int,这种操作可能会出现信息丢失的危险,这时必须显示地进行类型转换。
扩展转换:与窄化转换相对,这种转换可以不必显式地进行类型转换,因为新类型肯定能容纳原来类型的信息,不会造成任何信息的丢失。
Java允许我们把任何基本数据类型转换成别的基本数据类型,但是boolean除外,布尔型不允许任何类型的转换。
“类”数据类型不允许进行类型转化,为了将一种类转换成另一种,必须采用特殊的方法(向上转型/泛型)
截尾和舍入:
在执行窄化转换时,必须注意截尾与舍入的问题:例如:浮点型29.7转换为int,结果是29还是30。
将float或double转型为整形时,总是对该数字执行截尾。若想得到舍入误差,需要使用java.lang.Math中的round()方法。
如:
提升:
如果对基本数据类型执行算术运算或按位运算,只要类型比int小(即char,byte,short),那么运算前,这些值会自动转换成int,且最终生成的结果也是也是int类型。
如果想把结果赋给较小的类型(可能会出现信息丢失),就必须使用类型转换。
通常,如果一个float值与一个double值相乘,结果是double;如果一个int和一个long值相加,结果为long。
16.Java没有sizeof
C/C++中,sizeof()操作符可以告诉你数据项分配的字节数。C/C++中使用sizeof()最大的原因就是为了“移植”。Java不需要sizeof()的原因就是因为所有数据类型在所有机器中的大小都是相同的,不必考虑移植问题。