《编写高质量代码 改善Java程序的151个建议》书摘
例子1:三元操作符的陷阱
int i = 80; String str1 = String.valueOf(i < 100 ? 90 : 100); String str2 = String.valueOf(i < 100 ? 90 : 100.0); System.out.println(str1);// 输出:90 System.out.println(str2);// 输出:90.0
当你使用三元运算符,两边的操作数的类型不一致的时候,这就涉及到三元操作符的转换规则:
- 若两个操作数不可转换,则不做转换,返回值为Object类型;
- 若两个操作数是明确类型的表达式(比如变量),则按照正常的二进制数字来转换。int类型转换为long类型,long类型转换成float类型;
- 若两个操作数中有一个是数字S,另外一个是表达式,且其类型为T,那么,若数字S在T的范围内,则转换为T类型;若S超过了T的范围,则T转换为S类型;
- 若两个操作数字都是数字。则返回值类型为范围较大者。
例子2:一个关于自增的陷阱
int count = 0;
for(int i=0; i<=100; i++) {
count = count++;
}
System.out.println("count = " + count);//输出:count = 0
循环体内的“count = count++;”语句第一次执行时的详细处理步骤如下:
- JVM把count值(此时为0)拷贝到临时变量区;
- 将count的值加1(此时为1);
- 返回临时变量区的值(此时为0);
- 将返回值赋值给count(即count被赋值为0)。
用代码来表示则相当于以下语句:
public static int mockAdd(int count) {
int temp = count;
count = count + 1;
return temp;
}
不过,在C++中,“count = count++”与“count++”是等效的,PHP与Java则一样(不等效)
例子3:如何结合JS脚本处理易变的业务
//JS代码
var factor;
function formula(var1, var2) {
return var1 + var2 * factor;
}
//Java代码
int first = 11;
int second = 22;
String filePath = "D:/test.js";
ScriptEngineManager manager = new ScriptEngineManager();
// 获得一个javascript的执行引擎
ScriptEngine engine = manager.getEngineByName("javascript");
// 建立上下文变量
Bindings bind = engine.createBindings();
// 为js文件里的某个参数赋值
bind.put("factor", 5);
// 绑定上下文,作用域是当前引擎范围
engine.setBindings(bind, ScriptContext.ENGINE_SCOPE);
FileReader fr = new FileReader(filePath);
engine.eval(fr);// 执行js代码
// 判断是否为可调用的方法
if (engine instanceof Invocable) {
Invocable invocable = (Invocable) engine;
Double result = (Double) invocable.invokeFunction("formula", first,
second);
System.out.println("运算结果: " + result.intValue());
}
例子5:关于instanceof方法的使用
import java.util.Date;
public class InstanceofDemo {
public static void main(String[] args) {
System.out.println("Sting" instanceof Object);// 输出:true
// 分析:“String"是一个字符串,字符串又继承了Object
/***********************************/
System.out.println(new String() instanceof String);// 输出:true
// 分析:一个类的对象当然是它的实例
/***********************************/
System.out.println(new Object() instanceof String);// 输出:false
// 分析:Object是父类,其对象当然不是String类的实例了。
// 需要注意的是,这语句编译通过了,因为只要instanceof关键字的左右两个操作数有继承或实现关系,就可以编译通过
/***********************************/
System.out.println(null instanceof String);// 输出:false
// 分析:instanceof特有的规则:若左操作数是null,结果就直接返回false,不需要判断运算右操作数是什么类,类似短路运算。
// 因此,在使用instanceof操作符时,不用关心被判断的类(也就是左操作数)是否为null,这与我们经常用到的equals、toString方法不同。
/***********************************/
System.out.println((String) null instanceof String);// 输出:false
// 分析:不要看这里有个强制类型转换就认为结果是true。因为null是一个万用类型,也可以说它没类型,即使进行类型转换还是个null
/***********************************/
System.out.println('A' instanceof Character);// 编译报错
// 分析:
// 因为'A'是一个char类型,也就是一个基本类型,不是一个对象,instanceof只能用于对象的判断,不能用于基本类型的判断,所以编译报错
/***********************************/
System.out.println(new Date() instanceof String);// 编译报错
// 分析:因为Date类与String没有继承或实现关系,所以在编译时直接就报错了,instanceof操作符的左右操作数必须有继承或实现关系,否则会编译不通过
/***********************************/
System.out.println(new GenericClass<String>().isDateInstance("test"));// 输出:false
// 分析:此处T是个String类型,与Date之间没有继承或实现关系,为什么语句"return t instanceof Date"会编译通过呢?
// 因为Java的泛型是为编码服务的,在编译成字节码时,T已经是Object类型了,传递的实参是String类型,也就是说T的表面类型是Object,实际类型是String
// 所以,语句此处的"return t instanceof Date"语句就等价于"return Object instanceof Date"了
}
}
class GenericClass<T> {
// 判断是否是Date类型
public boolean isDateInstance(T t) {
return t instanceof Date;
}
}
《编写高质量代码 改善Java程序的151个建议》书摘的更多相关文章
- Code Simplicity–The Science of Software Development 书摘
Chapter1 Introduction That is the art and talent involved in programming—reducing complexity to simp ...
- 《CODE》书摘
2016-11-08 14:59:16 可以说英语词汇就是一种编码. 2016-11-08 15:19:04 实际上任何两种不同的东西经过一定的组合都可以代表任何种类的信息. 2016-11-08 1 ...
- 《C Elements of Style》 书摘
<C Elements of Style> 书摘 学完C语言和数据结构后,虽然能解决一些问题,但总觉得自己写的程序丑陋,不专业.这时候看到了Steve Oualline写的<C El ...
- Visual Studio Code 代理设置
Visual Studio Code (简称 VS Code)是由微软研发的一款免费.开源的跨平台文本(代码)编辑器,在十多年的编程经历中,我使用过非常多的的代码编辑器(包括 IDE),例如 Fron ...
- 我们是怎么做Code Review的
前几天看了<Code Review 程序员的寄望与哀伤>,想到我们团队开展Code Review也有2年了,结果还算比较满意,有些经验应该可以和大家一起分享.探讨.我们为什么要推行Code ...
- Code Review 程序员的寄望与哀伤
一个程序员,他写完了代码,在测试环境通过了测试,然后他把它发布到了线上生产环境,但很快就发现在生产环境上出了问题,有潜在的 bug. 事后分析,是生产环境的一些微妙差异,使得这种 bug 场景在线下测 ...
- 从Script到Code Blocks、Code Behind到MVC、MVP、MVVM
刚过去的周五(3-14)例行地主持了技术会议,主题正好是<UI层的设计模式——从Script.Code Behind到MVC.MVP.MVVM>,是前一天晚上才定的,中午花了半小时准备了下 ...
- 在Visual Studio Code中配置GO开发环境
一.GO语言安装 详情查看:GO语言下载.安装.配置 二.GoLang插件介绍 对于Visual Studio Code开发工具,有一款优秀的GoLang插件,它的主页为:https://github ...
- 代码的坏味道(14)——重复代码(Duplicate Code)
坏味道--重复代码(Duplicate Code) 重复代码堪称为代码坏味道之首.消除重复代码总是有利无害的. 特征 两个代码片段看上去几乎一样. 问题原因 重复代码通常发生在多个程序员同时在同一程序 ...
- http status code
属于转载 http status code:200:成功,服务器已成功处理了请求,通常这表示服务器提供了请求的网页 404:未找到,服务器未找到 201-206都表示服务器成功处理了请求的状态代码,说 ...
随机推荐
- Linux系统编程(22)——响应信号
进程对信号的响应 进程可以通过三种方式来响应一个信号: 1.忽略信号,即对信号不做任何处理,其中,有两个信号不能忽略:SIGKILL及SIGSTOP: 2.捕捉信号.定义信号处理函数,当信号发生时,执 ...
- android连续点击两次返回键退出代码
private long exitTime = 0; @Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCo ...
- AC大牛经典语录
超经典: 1. 为了世界的和平,为了女生的安全,我拼命做题,做题,做题! 2. A ac a day, keeps the doctor away! 3. from good to great ...
- android scrollview 简单的使用
以前写的Scrollview ,通常都是与Listview结合使用,不过因复杂可能新手不太懂,网上有许多文章,这里就不贴那个了DEMO了. 写了个简单的供大家参考:这样比较好理解(需要复杂的可以Q我 ...
- andorid 控件 Bootstrap3.0风格的控件 精美UI控件库
Bootstrap是Twitter推出的一个开源的用于前端开发的工具包.它由Twitter的设计师Mark Otto和Jacob Thornton合作开发,是一个CSS/HTML框架.Bootstra ...
- 【降维解法:最大字段和->最大子矩阵和->最终版最大子长方体和】【UVA10755】Garbage Heap
突然感觉刷完这一套专题后 码力有了质的飞跃,fighting 努力会有结果! 最大字段和是一个很经典的问题 O(n)算法 而对于最大子矩阵和 可以思考一个这样的想法 枚举上下边界i,j把i到j这一段的 ...
- 动态根据checkbox 增加Dom
<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" ...
- django学习笔记二:一个项目多个App项目搭建
django充许在一个项目中存在多个app,如一个大门户网站中可以包含论坛,新闻等内容,其中每一个模块称之为一个App,也可以理解为一个个独立的小型项目最终集成在一个门户网站中最终呈现给用户 本次测试 ...
- Oracle数据库游标的类型
游标是SQL的一个内存工作区,由系统或用户以变量的形式定义.游标的作用就是用于临时存储从数据库中提取的数据块.Oracle数据库的Cursor类型包含三种: 静态游标:分为显式(explicit)游标 ...
- Oracle sql语言模糊查询--like后面的通配符
关于like后面的条件,Oracle提供了四种匹配模式: 1,% :表示任意0个或多个字符.可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示. 比如 SELECT * FR ...