Thinking in java 第三章 - 操作符

Thinking in java 第三章 - 操作符

在最底层,Java中的数据是通过使用操作符来操作的。

1 更简单的打印语句

import static net.mindview.util.Print.*

public class Hello{
	public static void main(String[] args){
		print("Hello,it‘s:");
	}
}

2 使用Java操作符

有些操作符可能会改变操作数本身的值,这被称为副作用。那些能改变其操作数的操作符,最普遍的用途就是来产生副作用;但要记住,使用此类操作符生成的值,与使用没有副作用的操作符生成的值,与使用没有副作用的操作符生成的值,没有什么区别。

几乎所有的操作符都只能操作基本类型。例外的操作符是**=、==和!=,这些操作符能操作所有的对象(这也是对象易令人糊涂的地方)。除此之外,String类支持“+”和“+=**”。

3 优先级

当一个表达式中存在多个操作符时,操作符的优先级就决定了各部分的计算顺序。
总结:不记得优先级就使用小括号。

4 赋值

基本类型存储了实际的数值,而并非指向一个对象的引用,所以在赋值的时候,是直接将一个地方的内容复制到另一个地方。
对一个对象进行操作时,我们真正操作的是对对象的引用。所以倘若“将一个对象赋值给另一个对象”,实际是将“引用”从一个地方复制到另一个地方。这种特殊的现象通常称作“别名现象”,是Java操作对象的一种基本方式。

4.1 方法调用中的别名问题

将一个对象传递给方法时,也会产生别名问题:
方法参数为对象时,传递的是对象的引用,所以在方法体内对对象所做的操作实际上就是操作方法外的对象。

5 算术操作符


        要生成数字,程序首先会创建一个Random类的对象。如果在创建过程中没有传递任何参数,那么Java就会将当前时间作为随机数生成器的种子,并由此在程序每一次执行时都产生不同的输出。
        通过在创建Random对象时提供种子(用于随机数生成器的初始化值,随机数生成器对于特定的种子值总是产生相同的随机数序列),就可以在每一次执行程序时都生成相同的随机数,因此输出是可验证的。

通过Random类的对象,程序可生成许多不同类型的随机数字。做法很简单,只需调用方法nextInt()nextFloat()即可(也可以调用nextLong()或者nextDouble())。传递给**nextInt()**的参数设置了多产生的随机数的上限,而其下限为0,但是这个下限并不是我们想要的,因为它会产生除0的可能性,因此我们对结果做了加1操作。

5.1 一元加、减操作符
x = a * -b
x = a * (-b)

一元减号用于转变数据的符号,而一元加号只是为了与一元减号相对应,但是它唯一的作用仅仅是将较小类型的操作数提升为int

6 自动递增和递减(++、- -)

递增和递减操作符不仅改变了变量,并且以变量的值作为生成的结果。
这两个操作符各有两种使用方式,通常称为前缀式后缀式。对于前缀递增和前缀递减(如++a或–a),会先执行运算,在生成值。而对于后缀递增和后缀递减(如a++或a–),会想生成值,在执行运算。

它们是除那些涉及赋值的操作符以外,唯一具有“副作用”的操作符。也就是说,它们会改变操作数,而不仅仅是使用自己的值。

7 关系操作符

等于和不等于适用于所有的基本数据类型,而其他比较符不适用于boolean类型。

7.1 测试对象的等价性

关系操作符==和!=也适用于所有对象。
对于对象是否相等,Java默认比较的是对象的引用是否相等,两个对象即便拥有相同的属性值也是不相等的。对于基本数据类型直接使用==和!=即可;对于对象而言,可以使用equals方法来进行比较,
重点:equals默认的行为是比较引用。所以除非在自己的新类中覆盖了equals方法,否则不可能表现出我们希望的行为。
大多数的类库都实现了equals方法,以便来比较对象的内容,而非比较对象的引用。

8 逻辑操作符

与或非不可将一个非布尔值当做布尔值在逻辑表达式中使用。

注意,如果在应该使用String的地方使用了布尔值,布尔值会自动转换成适当的文本形式。

8.1 短路

一旦能够明确无误地确定整个表达式的值,就不再计算表达式余下部分了,将获得潜在的性能提升。

9 直接常量

如果程序中使用了直接常量,编译器可以准确地知道要生成什么样的类型,但有时候确实模棱两可的。如果发生这种情况,必须对编译器加以适当的“指导”,用与直接量相关的某些字符来额外增加一些信息。

直接常量后面的后缀字符标志了它的类型。LFD
十六进制前缀(0x、0X)

如果试图将一个变量初始化成超出自身表示范围的值(无论这个值的数值形式如何),编译器都会向我们报告一条错误信息。如果超出范围,编译器会将值自动转换成int型,并告诉我们需要对这次赋值进行“窄化转型”。

如果将比较小的类型传递给Interger.toBinaryString() 方法,则该类型将自动转换为int。

9.1 指数记数法
float expFloat = 1.39e-43f;
float expFloat = 1.39E-43f;
double expDouble = 47e47d;
double expDouble = 47e47;

如果编译器能够正确地识别类型,就不必在数值后附加字符。

10 按位操作符

按位操作符会对两个参数中对应的位执行布尔代数运算,并最终生成一结果。
与或非,异或

布尔类型作为一种单比特值对待,按位操作符具有与逻辑操作符相同的效果,只是它们不会中途“短路”。

11 移位运算符

移位操作符操作的运算对象也是二进制的“位”,移位运算符只可用来处理整数类型(基本类型的一种)。

  • 左位移操作符(<<)能按照操作符右侧指定的位数将操作符左边的操作数向左移动(在低位补0)。
  • “有符号”右移位操作符(>>)则按照操作符右侧指定的位数将操作符左边的操作数向右移动。“有符号”右移位操作符使用“符号扩展”:若符号为正,则在高位插入0;若符号为负,则在高位插入1。
  • Java中增加了一种“无符号”右移位运算符(>>>),它使用“零扩展”:无论正负,都在高位插入0。这一操作符是C或C++中所没有的。

如果对byte或short值进行这样的移位运算,得到的可能不是正确的结果。它们会先被转换成int类型,在进行右移操作,然后被截断,赋值给原来的类型,在这种情况下可能得到-1的结果。

如果对char、byte或者short类型的数值进行移位处理,那么在移位进行之前,它们会被转换为int类型,并且得到的结果也是一个int类型的值。
数字的二进制表现形式称为“有符号的二进制补码”

12 三元操作符 if-else

boolean-exp ? value0 : value1

13 字符串操作符 + 和 +=

这个操作符在Java中有一项特殊用途:连接不同的字符串。

字符串操作符有一些很有趣的行为。如果表达式以一个字符串起头,那么后续所有操作数都必须是字符串型(请记住,编译器会把双引号内的字符序列自动转成字符串)

14 使用操作符时常犯的错误

while(x=y){
	//......
}

上述代码在C/C++的环境中会产生错误或者不符合设计者的本意,但是在Java环境当中就不会产生类似的错误。(唯一不会得到编译时错误的情况是x和y都为布尔值。在这种情况下,x=y属于合法表达式。而在前面的例子中,则可能是一个错误。

15 类型转换操作符

类型转换的原意是模型铸造。在适当的时候,Java会将一种数据类型自动转换成另一种。

  • 窄化转换: 将能容纳更多信息的数据类型转换成无法容纳那么多信息的类型。就有可能面临信息丢失的危险。此时,编译器会强制我们进行类型转换。
  • 扩展转换: 不必显式地进行类型转换,因为新类型肯定能容纳原来类型的信息,不会造成任何信息的丢失。
15.1 截尾和舍入

floatdouble转型为整数值时,总是对该数字执行截尾。如果想要得到舍入的结果,就需要使用java.lang.Math中的 round() 方法。

由于round()是java.lang的一部分,因此使用它时不需要而外导入。

15.2 提升

如果对基本数据类型执行算术运算或按位运算,大家会发现,只要类型比int小(即char、byte、或者short),那么在运算之前,这些值会自动转换成int。

通常,表达式中出现的最大的数据类型决定了表达式最终结果的数据类型。

16 Java没有sizeof

在C和C++中,sizeof()操作符可以告诉你为数据项分配的字节数。在C和C++中,需要使用sizeof()的最大原因是为了移植

Java不需要 sizeof() 操作符来满足这反面的需求,因为所有的数据类型在所有的机器中的大小都是相同的。我们不必考虑移植问题——它已经被设计在语言当中了。

17 操作符小结

char、byteshort中,我们可看到使用算术操作符中数据类型提升的效果。

对于char、byte或者short,复合赋值并不需要类型转换。尽管他们执行类型提升,但也会获得与直接算术运算相同的结果。仍在另一方面,省略类型转化可使代码更加简练。

18 总结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值