• Java直接量(字面量)及 Java运算符优先级


    直接量是指在程序中通过源代码直接给出的值,例如在int a = 5;代码中,为变量 a 所分配的初始值 5 就是一个直接量。

    直接量的类型

    并不是所有的数据类型都可以指定直接量,能指定直接量的通常只有三种类型:基本类型、字符串类型和 null 类型。具体而言,java 支持如下 8 种类型的直接量。

    1)int 类型的直接量

    在程序中直接给出的整型数值,可分为二进制、十进制、八进制和十六进制 4 种,其中二进制需要以 0B 或 0b 开头,八进制需要以 0 开头,十六进制需要以 0x 或 0X 开头。例如 123、012(对应十进制的 10)、0x12(对应十进制的 18)等。

    2)long 类型的直接量

    在整型数值后添加 l 或 L 后就变成了 long 类型的直接量。例如 3L、0x12L(对应十进制的 18L)。

    3)float 类型的直接量

    在一个浮点数后添加 f 或 F 就变成了 float 类型的直接量,这个浮点数可以是标准小数形式,也可以是科学计数法形式。例如 5.34F、3.14E5f。

    4)double 类型的直接量

    直接给出一个标准小数形式或者科学计数法形式的浮点数就是 double 类型的直接量。例如 5.34、3.14E5。

    5)boolean 类型的直接量

    这个类型的直接量只有 true 和 false。

    6)char 类型的直接量

    char 类型的直接量有三种形式,分别是用单引号括起来的字符、转义字符和 Unicode 值表示的字符。例如‘a’,‘\n’和‘\u0061’。

    7)String 类型的直接量

    一个用双引号括起来的字符序列就是 String 类型的直接量。

    在大多数其他语言中,包括 C/C++,字符串作为字符的数组被实现。然而,在 Java 中并非如此。在 Java 中,字符串实际上是对象类型。在教程后面你将看到,因为 Java 对字符串是作为对象实现的,因此,它有广泛的字符串处理能力,而且功能既强又好用。

    8)null 类型的直接量

    这个类型的直接量只有一个值,即 null。

    在上面的 8 种类型的直接量中,null 类型是一种特殊类型,它只有一个值:null。而且这个直接量可以赋给任何引用类型的变量,用以表示这个引用类型变量中保存的地址为空,即还未指向任何有效对象。

    直接量的赋值

    通常总是把一个直接量赋值给对应类型的变量,例如下面代码都是合法的。

    int a = 5;
    char c = 'a';
    boolean b = true;
    float f = 5.12f;
    double d = 4.12;
    String name = "CSDN网";
    String url = "http://csdn.net";

    除此之外,Java 还支持数值之间的自动类型转换,因此允许把一个数值直接量直接赋给另一种类型的变量,这种赋值必须是系统所支持的自动类型转换,例如把 int 类型的直接量赋给一个 long 类型的变量。

    String 类型的直接量不能赋给其他类型的变量,null 类型的直接量可以直接赋给任何引用类型的变量,包括 String 类型。boolean 类型的直接量只能赋给 boolean 类型的变量,不能赋给其他任何类型的变量。

    关于字符串直接量有一点需要指出,当程序第一次使用某个字符串直接量时,Java 会使用常量池(constant pool)来缓存该字符串直接量,如果程序后面的部分需要用到该字符串直接量时,Java 会直接使用常量池(constantpool)中的字符串直接量。

    提示:

    • 由于 String 类是一个典型的不可变类,因此 String 对象创建出来的就不可能改变,因此无需担心共享 String 对象会导致混乱。
    • 常量池(constant pool)指的是在编译期被确定,并被保存在已编译的 .class 文件中的一些数据,它包括关于类、方法、接口中的常量,也包括字符串直接量。


    看如下程序:

     
    
    1. String s0 = "hello";
    2. String s1 = "hello";
    3. String s2 = "he" + "llo";
    4. System.out.println(s0 == s1);
    5. System.out.println(s0 == s2);

    运行结果为:

    true
    true

    Java 会确保每个字符串常量只有一个,不会产生多个副本。例子中的 s0 和 s1 中的“hello”都是字符串常量,它们在编译期就被确定了,所以 s0 = s1 返回 true。而“he”和“llo”也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它本身也是字符串常量,s2 同样在编译期就被解析为一个字符串常量,所以 s2 也是常量池中“hello”的引用。因此,程序输出 s0 == s1 返回 true,s1 == s2 也返回 true。

    Java运算符优先级

    所有的数学运算都认为是从左向右运算的,java 语言中大部分运算符也是从左向右结合的,只有单目运算符、赋值运算符和三目运算符例外,其中,单目运算符、赋值运算符和三目运算符是从右向左结合的,也就是从右向左运算。

    乘法和加法是两个可结合的运算,也就是说,这两个运算符左右两边的操作数可以互换位置而不会影响结果。运算符有不同的优先级,所谓优先级就是在表达式运算中的运算顺序。

    一般而言,单目运算符优先级较高,赋值运算符优先级较低。算术运算符优先级较高,关系和逻辑运算符优先级较低。多数运算符具有左结合性,单目运算符、三目运算符、赋值运算符具有右结合性。

    Java 语言中运算符的优先级共分为 14 级,其中 1 级最高,14 级最低。在同一个表达式中运算符优先级高的先执行。表 1 列出了所有的运算符的优先级以及结合性。
     

    表1 运算符的优先级
    优先级运算符结合性
    1()、[]、{}从左向右
    2!、+、-、~、++、--从右向左
    3*、/、%从左向右
    4+、-从左向右
    5«、»、>>>从左向右
    6<、<=、>、>=、instanceof从左向右
    7==、!=从左向右
    8&从左向右
    9^从左向右
    10|从左向右
    11&&从左向右
    12||从左向右
    13?:从右向左
    14=、+=、-=、*=、/=、&=、|=、^=、~=、«=、»=、>>>=从右向左


    使用优先级为 1 的小括号可以改变其他运算符的优先级,即如果需要将具有较低优先级的运算符先运算,则可以使用小括号将该运算符和操作符括起来。例如下面的表达式:

    (x-y)*z/5

    在这个表达式中先进行括号内的减法运算,再将结果与 z 相乘,最后将积除以 5 得出结果。整个表达式的顺序按照从左向右执行,比较容易理解。

    再来看一个复杂的表达式,如下所示。

    --y || ++x && ++z;

    这个表达式中包含了算术运算符和逻辑运算符。根据表 1 中列出的优先级,可以确定它的执行顺序如下:
    ① 先计算 y 的自减运算符,即 --y。
    ② 再计算 x 的自增运算符,即 ++x。
    ③ 接着计算 z 的自增运算符,即 ++z。
    ④ 由于逻辑与比逻辑或的优先级高,这里将 ② 和 ③ 的结果进行逻辑与运算,即 ++x && ++z。
    ⑤ 最后将 ④ 的结果与 ① 进行逻辑或运算,即 --y||++x&&++z。

    如果没有上述对该表达式执行顺序的说明,第一眼看到它时将很难识别优先级。对于这类问题,可以通过添加小括号使表达的顺序更加清晰,而不用去查优先级表。如下所示为改进后的表达式。

    (--y)||((++x)&&(++z));

    技巧:记住这么多运算符的优先级是比较困难的,因此读者应该在实际应用中多多练习。

    因为 Java 运算符存在这种优先级的关系,因此在做 SCJP 的时候或者某些公司的面试题,有如下 Java 代码:

    int a = 5;
    int b = 4;
    int c = a++- --b*++a/b-- >>2%a--;

    问 c 的值是多少?这样的语句实在太恐怖了,即使多年的老程序员看到这样的语句也会眩晕。这样的代码只能在考试中出现,作为一个程序员如果写这样的代码,恐怕他马上就得走人了,因为他完全不懂程序开发。

    源代码就是一份文档,源代码的可读性比代码运行效率更重要。 因此在这里要提醒大家:

    • 不要把一个表达式写得过于复杂,如果一个表达式过于复杂,则把它分成几步来完成。
    • 不要过多地依赖运算符的优先级来控制表达式的执行顺序,这样可读性太差,尽量使用()来控制表达式的执行顺序。
  • 相关阅读:
    LeetCode题目笔记——2486. 追加字符以获得子序列
    架构师考试周报三
    HDFS、MapReduce原理--学习笔记
    如何选择适合广西地区气候条件的建筑模板?
    Java NIO Selector选择器源码分析
    基于MATLAB的函数拟合
    实战案例:用 PySpark ML 构建流失预测模型
    做程序员2年我发现的宝藏软件……
    Manjaro如果yay使用了aur的清华源,出现报错,解决方法
    苹果 Vision Pro 头显新专利:增加重量减轻颈部压力
  • 原文地址:https://blog.csdn.net/weixin_42673574/article/details/133814055