`
zhang.jianjun
  • 浏览: 19523 次
  • 性别: Icon_minigender_1
  • 来自: 青岛
最近访客 更多访客>>
社区版块
存档分类
最新评论
  • NGG: 个人建议: 正确的做法应该是把样式放到外部css文件中,使用 ...
    js日期选择器

【JAVA优化编程】表达式、语句与保留字之——(1)表达式

阅读更多

    表达式与语句是任何程序设计语言的基础,也是开发大型软件系统的最底层的“标准散件”,是开发人员掌握任何程序设计语言的基础。无论多么庞大的软件系统,都是由开发语言的表达式与语句搭建而成的,因此,不容忽视。也许你可能对这部分内容的概念较为熟悉,但在实际的程序设计中,却经常在方面犯错误,而且通常情况下,这些问题还比较隐蔽,极不易被发现,希望你能通过本章的学习可以避免在这些方面犯错误,并且提高所编写代码的性能。

 

1  表达式

    在Java语言中表达式分为两种:一元操作符和二元操作符 。一元操作符和二元操作符如下表所示。

一元操作符
操作符 适用范围 结合规则
++, -- 算数,字符 从右至左
+, - 算数 从右至左
- 整数 从右至左
! 布尔 从右至左
(type) 任意 从右至左

 

二元操作符
操作符 适用范围 结合规则
*, /, % 算术 从左至右
+, - 算术 从左至右
+ 字符串 从左至右
<< 整型数 从左至右
>> 整型数 从左至右
>>> 整型数 从左至右
<, >, <=, >= 算术、字符 从左至右
instanceof 对象x类型 从左至右
==, != 元数据 从左至右
==, != 对象 从左至右
&, ^, | 整型数和布尔值 从左至右
&&, || 布尔值 从左至右

 

1.1  括号规则

    这里没有提到关于操作符运算优先级的知识,因为记住这些运算符的优先级是件很麻烦的事,而且稍有疏忽就有可能弄错,现在给你一个“放之四海皆准”的办法来解决这个令人头疼的问题——合理运用括号,表达你期望的运算优先级。例如下面的表达式:

        x = ((a | b) && (a & c)) || (m < n)

    我们只要合理地应用括号规则就可以避免使用默认优先级出现的错误。如果你觉得上面的表达式很容易应用默认优先级来达到你的期望结果,根本用不着使用括号加以区分,但是如果比这个表达式再复杂两倍或三倍的表达式,恐怕你就不会觉得是件容易的事了,因为较长且繁琐的表达式,很难让你一目了然,极有可能产生你所不期望的运算优先级。


1.2  简单规则

    有些时候,我们为了书写方便,经常会使用一些较为复杂的复合表达式,例如:

boolean isTrue = (getObject() != null);
userName = userManager.getUsers().getUserNames()[i];

 

    这些语句在Java语言中都是正确的,而且这样可以节省你的编程时间,提高程序的编译效率,但是如果应用不当同样会产生很多问题,导致程序运算逻辑上的错误,例如:

        x = i >= j && m < n && y + z <= d;

    上面的表达式是较为复杂的,而且很难理解,即使是开发人员自己阅读恐怕都有些困难,其他人员就更难以了解其意图了,因此这样复杂的表达式应尽量避免使用。

 

1.3  单一意图规则

    表达式应该尽量表达单一意图,也就是说,最好一个表达式只做一件事,例如,赋值表达式就只负责为一个变量赋值,一个运算表达式就只负责完成一个运算过程。这样就可以使程序员所表达的意图更为清晰,不会产生一些隐蔽的错误。否则就容易产生一些你所不期望的错误,而且降低程序的可读性,例如下面的语句:

int i = 0;
if ((i=++j) == (x++)) {
    ... ...
}
 

    其目的是在对i赋值,x加1后再比较二者的值,这样书写没有任何语法上的错误,但是却使程序难以理解,降低了程序的可读性,如果存在逻辑上的错误也很难排除,正确解决的办法是将表达不同意图的表达式分开,例如上面的语句可以书写成:

int i = 0;
i = ++j;
x++;
if (i == x) {
    ...
}
 

    通过对上面程序的分解,你可以看到修正后的代码,让人看起来思路更为清晰,逻辑也非常清楚。这样程序所表达的意图就一目了然,增强了程序的可读性,并且不易产生隐蔽的错误。

 

1.4  方法返回值比较规则

    有时候为了使程序书写简洁,我们经常在判断语句中直接通过方法的返回值来作为条件判断的比较项,例如:假设方法obj.getAge()返回一个整数而且变量i也是一个整数,请看下面的语句。

if (obj.getAge() == i) {
    ...
}
 

    上面这个语句在语法上是没有任何问题的,但笔者曾经却遇到过这样一个奇怪的问题,即使当obj.getAge()方法的返回值与i中的数值相同,条件obj.getAge() == i 却为假,记得这是在JDK1.2中遇到的一个问题,耗费了笔者很长的时间才找到,现在的JDK版本已经解决了这个问题,但是笔者还是建议你尽量不要这样书写,下面的书写方式是值得提倡的:

int tmp = obj.getAge();
if (tmp == i) {
    ...
}
 

 

1.5  字符串比较规则

 

    字符串比较

    字符串(String)是Java语言中的核心类,而且应用广泛。但是这里有一个极容易陷入的误区,当你比较两个字符串变量时,可能会写成下面的样子:

if (userName == myName) {
    ...
}
 

    在Java语言中不存在语法的问题,但是你却不一定能得到你所预期的结果。因为这种比较方式比较的是两个对象的引用,而不是比较它们所引用的对象。如果上面语句中的

        userName = "张三";

        myName = "李四";

    这样表达式“userName == myName”的返回值就为假,这是因为这两个字符串变量的值不一样,而且它们的引用也不一样。假设二者的引用相同,那么返回值就为真,其比较结果显然是出乎我们意料的,因为这不是我们所期望的,引起这个问题的根本原因,就是你所采用的比较方法不对,应该采用下面的比较方式:

if (userName.equals(myName)) {
    ...
}
 

    String类中的equals()方法专门用来比较字符串的值,而不是比较字符串对象的引用,因此,采用上面的方法将返回你所期望的结果。这里需要提醒你一下,使用“==”比 较用equals()方法比较对象是否相等,更为快速,你应该在适当的前提下,尽可能的使用“==”而不使用equals()方法。

 

    字符串驻留

    上面我们讨论了字符串比较的知识要点,不妨再延伸一下,介绍字符串驻留的知识。在字符串类String中有一个叫做intern()的方法,这个方法用来创建一个唯一字符串集合的驻留池,例如:

        userName = userName.intern();

    就相当于将字符串添加到这个驻留池中,如果这个驻留池中原先并不存在这个值,并且返回对这个已驻留字符串的引用,这样已驻留的字符串就可以通过“==”彼此之间做比较操作了,采用这个方法比采用equals()方法更为廉价,而且运行速度更快,下面是一个字符串比较的例子:

// 字符串比较
public class CompareString {
    public static void main(String args[]) {
        String str = new String("张三");
        // 没有做驻留处理
        if (str == "张三") {
            System.out.println("相同");
        } else {
            System.out.println("不同");
        }
        // 做了驻留处理
        str = str.intern();
        if (str == "张三") {
            System.out.println("相同");
        } else {
            System.out.println("不同");
        }
    }
}
 

    在上面的例子中,第一个if 语句中str == "张三" 比较后的返回值为假,这是因为str 是对显式声明字符串“张三”的拷贝的引用,当“张三”自身是一个驻留字符串的时候,相应的引用也变得截然不同了。在上例中的第二个if 语句中str == "张三" 比较后的返回值为真,这是因为str 已经被驻留,并且对方法intern() 的返回值的引用与对显式声明字符串“张三”的引用相同,因为显式声明字符串正是将字符串内容保存在驻留字符串池中的过程。字符串中intern()方法的执行效率很高,因此在不必须要求采用equals() 方法做字符串比较时,你可以采用字符串驻留的方法,以提高系统的性能。

分享到:
评论

相关推荐

    python学习笔记—pythone 33个保留字及其含义

    pythone 33个保留字及其含义正文可以用代码查询python到底有哪些保留字注意: 正文 序号 保留字 含义 1 and 用于表达式运算,逻辑与操作 2 as 用于类型转换 3 assert 断言,用于判断变量或条件表达式的值...

    编译原理课设和实验:PL0编译器扩充

    (1)增加单词:保留字 ELSE,FOR,STEP,UNTIL,RETURN 运算符 +=,-=,++,--,&&,||,! (2)修改单词:不等号# 改为 (3)增加条件语句的ELSE子句,要求:写出相关文法,语法图,语义规则。 含源代码,注释...

    编译原理实验 编译原理

    (1)增加单词:保留字 ELSE,FOR,TO,DOWNTO,RETURN 运算符 +=,-=,++,-- (2)修改单词:不等号# 改为 (3)增加条件语句的ELSE子句 2. 课程设计 基本内容(成绩范围:“中”、“及格”或“不及格”) (1)...

    SQL 去除字段中符号,只保留数字和字母

    --去除字段中符号,只保留数字和字母sql-- create FUNCTION DBO.REMOVE_SYMBLE(@S VARCHAR(100)) RETURNS VARCHAR(100) AS BEGIN DECLARE @SQL VARCHAR(100) SET @SQL=''

    编译原理课程设计(报告+源码) 广东工业大学 07级

    1. 增加单词:保留字 ELSE,FOR,TO, DOWNTO 运算符 +=,- =,++,- - 修改单词:不等号# 改为 &lt;&gt; 2. 增加条件语句的ELSE子句 3. 扩充赋值运算 += 和 -= 4.扩充语句(Pascal的FOR语句): ①FOR &lt;变量&gt;:=...

    表达式求值(2)选作.cpp

    end为保留字,表示程序段结束;用?表示输出指定变量的值,则可以设计出比较复杂的表达式(即一个可顺序执行语句序列)。例如,如果有如下语句段: abc=10 def=8 c=abc+def abc=abc+5-c*2 ? c ? abc end 则输出为...

    数学表达式求值

    带有变量的中缀表达式是常见的数学表达式。如果规定变量由长度不...end为保留字,表示程序段结束;用?表示输出指定变量的值,则可以设计出比较复杂的表达式(即一个可顺序执行语句序列)。例如,如果有如下语句段:

    正则表达式

    例如:下面的正则表达式匹配的就是位于单引号或双引号之内的所有字 符.但是,它要求开始和结束的引号匹配(例如两个都是双引号或者都是单引号): /[' "] [^ ' "]*[' "]/ 如果要求开始和结束的引号匹配,我们可以...

    编译原理课程设计——对PL/0作出修改扩充

    其中,语句①的循环变量的步长为1,语句②的循环变量的步长为-1。 选做内容: (1)增加运算:++ 和 --。(实现) (2)增加类型:① 字符类型; ② 实数类型。(未实现) (3)扩充函数:① 有返回值和返回语句;...

    编译原理课程设计

    (1)增加单词:保留字 ELSE,FOR,TO,DOWNTO,RETURN 运算符 +=,-=,++,―― 其中FOR,TO,DOWNTO,RETURN属于选做内容。 (2)修改单词:不等号# 改为 (3)增加条件语句的ELSE子句 我在本次实验中实现...

    SQL书写规范;书写优化性能建议;经验性规则

    1、sql语句的所有表名、字段名全部小写,系统保留字、内置函数名、sql保留字大写。 2、连接符or、in、and、以及=、、&gt;=等前后加上一个空格。 3、对较为复杂的sql语句加上注释,说明算法、功能。 注释风格:注释...

    C语言程序设计标准教程

    1.表达式语句 2.函数调用语句 3.控制语句 4.复合语句 5.空语句 1.表达式语句 表达式语句由表达式加上分号“;”组成。其一般形式为: 表达式; 执行表达式语句就是计算表达式的值。例如: x=y+z; 赋值语句y+z; ...

    JavaScript权威指南-第六版

     2.4 标识符和保留字28  2.5 可选的分号30  第3章 类型、值和变量32  3.1 数字34  3.2 文本38  3.3 布尔值43  3.4 null和undefined44  3.5 全局对象45  3.6 包装对象46  3.7 不可变的原始值和可变的对象...

    Java面试宝典(传说中的葵花宝典).doc

    java中的保留字,现在没有在java中使用。 3、说说&和&&的区别。 &和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则...

    Java开发技术大全 电子版

    2.5.2表达式语句和空语句59 2.5.3块语句60 2.5.4if~else分支语句61 2.5.5多路分支switch~case语句69 2.5.6当型循环while语句71 2.5.7直到型循环do~while语句72 2.5.8当型循环for语句74 2.5.9循环的嵌套78 ...

    《由浅入深学C++-基础、进阶与必做300题》pdf格式 (完整版 带目录

    1.3.3 保留字 8 1.3.4 符号 8 1.4 C++集成开发环境——DEV-C++ 9 1.4.1 选择C++编译器 9 1.4.2 安装DEV-C++ 10 1.4.3 DEV-C++ IDE简介 11 1.5 第一个C++程序——Hello World 11 1.5.1 创建源程序 11 1.5.2 ...

    编译原理课后习题答案(蒋立源第三版)

    上述关键字在C语言中均为保留字。 4解:C语言中括号有三种:{},[],()。其中,{}用于语句括号;[]用于数组;()用于函数(定义与调用)及表达式运算(改变运算顺序)。C语言中无END关键字。逗号在C语言中被视...

    资料NCT等级测试-Python编程三级真题测试卷1.doc

    使用函数的主要目的是减低编程难度和代码重用 C.Python 使用 del 保留字定义一个函数 D.函数是一段具有特定功能的语句组 5.在Python中,input()函数的返回结果的数据类型为( ) A.Number型 B.String型 C....

    JAVA笔试题集锦(1-30)基础部分

    1、作用域public,private,protected,以及不写时的区别 答:区别如下: 作用域 当前类 同一package 子孙类 其他package public √ √ √ √ protected √ √ √ × ...答:java中的保留字,现在没有在java中使用

Global site tag (gtag.js) - Google Analytics