《Java开发手册》学习进程之第3章运算符详解

运算符重载是指同一个运算符在不同的情况下执行不同的操作。

例如,“+”运算符在Java中就有不同的功能:

  • 加法运算
  • 数值正号
  • 字符串连接

特别要注意要在字符串连接的表达式中字符串与其他基本数据类型的变量的连接问题。

例如:

(1)System.out.println(a + m + n)中,a为一String对象,m和n为int型变量(也可以是byte,short,float等其他基本数据类型)。根据此表达式中的运算符优先级可知,a先与m相连接,其合并为一个字符串,然后再与n连接并以字符串的形式输出。而不是m和n相加后再与字符串a连接。

(2)System.out.println(m + n + a)中,m与n先相加,然后再与字符串a相连接。这与上面的情况相反。

在有取余运算符参与的表达式中,要注意以下几种情况:

  • “15%-4”运算结果为“3”,结果的符号与右边操作数无关
  • “-15%4”运算结果为”3”,结果的符号与左边操作数相关
  • “6.8%6.3”运算结果为”0.5“,浮点数也可以求余
  • “15.0%0”运算结果为”NaN“,表示不知道结果是什么
  • “15%0”运行报错,与整除中除以0是一样的

自增、自减运算符不会对其进行类型提升。

”NaN“表达的意思是”不知道“,故”NaN“之间无法用”==“和”!=“相互比较,只能返回”false“。

将数值与无穷进行是有意义的,而与”NaN“进行比较没有意义,Java中规定任何数值与”NaN“进行大小比较永远返回”false“。

三元运算符中的结果表达式1和2如果为基本类型,则要求其是兼容的。如果为引用类型,则永远是可以的,因为三元表达式的返回类型将设置为两个表达式类型的最小公共父类类型。

移位运算中,有些情况不符合我们正常的思维。比如下面这个例子:

public class Sample3_14
{

    public static void main(String[] args)
    {
        int i = 88 << 32;
        long l = 67 >> 64;
        System.out.println("i = " + i);
        System.out.println("l = " + l);

    }

}

按我们对移位运算的正常理解,32位的整型数值88被左移了32位后,整个位模式都显示为0,所以最后结果为0,但在最后结果中会发现i的值没变。这是因为,在移位前,Java系统首先把被移数的位数与所要移的位数求余,然后才根据余数进行移位。

赋值运算中,要注意一个小细节。赋值运算符”=“的运算顺序是从右到左,即先把”=“号右边的表达式算完,然后再将其值赋给”=“右边的变量。所以”int k += 1”无法通过编译。因为”int k += 1“实际上等同于”int k = k + 1“,而这个式子首先计算”k + 1“,但是k并没有被定义,故”int k += 1“明显错误。正确的做法是先将”k”初始化为某个值,然后再进行”+=“运算。

另外,类型于”+=“的赋值运算符还有”-=“、”>>>=“等。而整个”X +=Y“相当于”X=(<X的类型>)(X+Y)“,即具有隐含的强制类型转换。

 

时间: 2024-08-19 02:08:14

《Java开发手册》学习进程之第3章运算符详解的相关文章

《Java开发手册》学习进程之第10章构造器应用

构造器与返回类型: 构造器没有返回类型,若将返回值类型(包括void)添加到构造器上,编译不会报错,但此时不再是构造器了,而只是一个与所在类同名的方法而已. 构造器与方法是两个不同的概念: 构造器不能像方法一样能被对象引用调用. 构造器是创建对象时需执行的代码,由new调用.方法是类或对象具有的行为,由引用调用. 无参数的构造器(资料来源:<Java核心技术卷1(中文第9版)>127页): 如果在编写一个类时没有编写构造器,那么系统就会提供一个无参数的构造器.这个构造器将所有实例域设置为默认值

【转】线程池体系介绍及从阿里Java开发手册学习线程池的正确创建方法

jdk1.7中java.util.concurrent.Executor线程池体系介绍 java.util.concurrent.Executor : 负责线程的使用与调度的根接口  |–ExecutorService:Executor的子接口,线程池的主要接口  |–ThreadPoolExecutor:ExecutorService的实现类  |–ScheduledExecutorService:ExecutorService的子接口,负责线程的调度  |–ScheduledThreadPo

从阿里Java开发手册学习线程池的正确创建方法

前言 最近看阿里的 Java开发手册,上面有线程池的一个建议: [强制]线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险. 结合最近面试的经历,发现这条建议还是十分有用的,因为自己经常使用Executors提供的工厂方法创建线程池,所以忽略了线程池内部的实现.特别是拒绝策略,面试被问到两次,因为使用Executors创建线程池不会传入这个参数而使用默认值所以我们常常忽略这一参

《Java开发手册》学习进程之第16章多线程

多线程编程可以使程序具有两条或两条以上的并发执行线索,就像日常工作中由多人同时合作完成一个任务一样.这在很多情况下可以改善程序的响应性能,提高资源的利用效率. 例如,开发一个网上购物时自动邮件通知的程序,在用户单击"提交"按钮确认订单时,一方面要显示信息提示用户订单已确认,一方面应该自动给用户发送一份电子邮件. 如果是单线程模式,则需要等待邮件发送完成之后,再显示提示信息,由于邮件发送的过程相对较慢,用户可能要经过漫长的等待才看到确认信息,界面响应性能不是很好. 而显示订单确认信息与发

《Java开发手册》学习进程之第7章访问控制符

类的访问控制符: 虽然访问控制符有四种,但针对外部类来说,只需要公共的和默认的就够了. public表示任何类都可以使用该类. 当一个类被定义为public的时候,它就可以在任何类里被访问了. 成员的访问控制: 成员(即成员变量和方法)能被其他类访问主要取决于两个方面因素: 成员变量和方法所在类的可见性是其能被正常访问的前提条件: 其次是成员变量和方法的访问控制符直接决定了是否可以被访问. Static关键字:  Java中没有全局变量的概念. 若static修饰成员变量,当生成类的对象时,该类

《Java开发手册》学习进程之第15章内部类

非静态内部类: 从非静态内部类外面看,完全可以将其看成是外部类的一个非静态成员,与普通的成员没有什么区别.只是这个成员不再是基本数据类型,也不再是对象引用,而是一个类,由一个类来扮演成员的角色. 内部类的访问限制修饰符除了外部类的public和默认外,还可以添加private和protected. 虽然内部类位于外部类的类体中,但编译后内部类与外部类各自产生一个类文件. 因为非静态内部类扮演的是外部类非静态成员的角色,而非静态成员只有在所属对象存在的情况下才存在,因此非静态内部类在创建了外部类对

《Java开发手册》学习进程之第9章接口

接口中的成员变量: 与类不同,在接口中只能定义常量属性,并且可以不必使用public.statict和final修饰,因为即使不使用这些修饰符,编译时也会为其加上,即接口中的成员变量隐含的是"public static final"的.另外,必须在声明的同时给出其值. 接口中的方法: 接口中的方法必须是抽象的,原因是接口只是代表了一个契约,表示实现它的类有什么样的功能,具体实现是由实现它的类完成的. 接口中的方法必须是public.abstract的,不能像接口中的成员变量一样使用fi

《Java开发手册》学习进程之第6章对象和类

传统的过程化程序设计通过设计一系列的过程——算法来求解问题.这些过程一旦被确定,下一步就要开始寻找存储数据的方式,即“程序 = 算法 + 数据结构”.而面向对象的程序设计(即OOP,Object Oriented Programming)调换了这个次序,将数据放在第一位,之后再考虑操纵数据的算法. 在OOP中,程序被看作是相互协作的对象集合,每个对象都是某个类的实例.所有类构成了一个通过继承关系相联系的层次结构. 由于面向过程的编程模式是先将一系列过程(即函数)设计好再通过参数输入求解的,所以对

《Java开发手册》学习进程之第2章基本数据类型

2.1  数据类型 Java表示整数常量时,默认情况下为int型:若整数常量前面有个0,则表示八进制数:若整数常量前面有个‘0x’或’0X’,则表示十六进制. long型常量需在后面加个’l’或’L’.用System.out.println()方法输出时,其后缀名并不会输出. 如果某个浮点值没有使用float关键字(’f‘或’L‘)作为后缀名,则系统默认为double型.同long型常量一样,其后缀名也并不会输出. 注意:别把double型的常量赋值给float型的变量,把长度为8字节的doub