如果常量类进行改变时,只编译常量类,而使用常量的类不重新编码,这样改动实际上算没有生效(转)

 

在Java开发过程中有很多通用的准则,遵守这些准则能够避免很多不必要的错误发生,让代码的质量更高,下面的内容为书籍第一章《Java开发中通用的方法和准则》的阅读笔记。

一、不要在常量和变量中出现易混淆的字母

例如数字1和小写字母l容易混淆,数字0和字母o容易混淆,因此在变量或常量命名时需要避免两个同时出现。 
另外命名最好遵守Java编码规范:包名全小写,类名首字母全大写,常量全部大写并用下划线分隔,变量采用驼峰命名法等等。

二、不要让常量蜕变成变量

常量应该保证在编译期就确定其值不变,而不是在运行期设置其值。书中列举了一个定义常量值等于随机数的例子,这样编译不会有问题,但是是不可取的作法。

三、三元操作符的类型勿必一致

三元操作符经常作if-else的简写使用,但是需要注意保证三元操作符的类型都是一致的,不然可能出现意想不到的问题。 
例如书中所举示例:String.valueOf(80<90?90:100)返回结果是90,而String.valueOf(80<90:100.0)的返回结果却是90.0,就因为类型不一致导致。具体的原因与三元操作符的转换规则有关系,对于该示例若两个操作数都是数字,则返回值类型为返回较大者。所以造成返回值不同。

四、避免带有变长参数的方法重载

变长参数能够提高方法的灵活度和可复用性,不过在使用过程中需要注意变长参数必须是方法参数的最后一个参数,同一个方法不能够定义多个变长参数,另外需要特别注意带有变长参数的方法不要进行重载,因为这样如果参数类型相同时会引起“不知道调用的是哪个方法”的疑惑,代码可读性变差,而且可能导致潜在的问题。

五、别让null值和空值威胁到变长方法

在调用变长参数的方法时,不要将参数直接传null值,可能引起不必要的错误,应该传指定参数类型的数据(明确类型的数据)。

六、覆盖变长方法也要循规蹈矩

子类覆盖父类的变长方法时一定要注意子类的方法参数列表保证与被重写的方法参数列表相同。(这里书中有一个很好的例子进行说明,限于篇幅不列举了)

七、警惕自增的陷阱

书中举了一个很有意思的例子, int count = 0; for( int i = 0; i < 10; i++ ){ count = count++; } System.out.println(count);最后输出的结果是0。因为每次循环都会把count赋值为0。所以在编写代码时要特别警惕自增的陷阱。

八、少用静态导入

对于静态导入,需要遵循两个规则:

1. 不使用*(星号)通配符,除非是导入常量类或接口; 
2. 方法名必须是具有明确、清晰表象意义的工具类,才可以使用静态导入。
这样主要是为了增强代码的可读性。

九、不要在本类中覆盖静态导入的变量和方法

在本类覆盖静态导入的变量和方法时,方法执行时会遵循“最短路径”原则,本类的方法和变量会优先,不过这样容易引起理解上的困难,导致代码可读性变差。

十、养成好习惯,显式声明UID

在实现Serializable接口时,常常需要增加一个serialVersionUID,这个值是用来定义类的版本的,显示声明UID可以避免对象不一致。

十一、避免用序列化类在构造函数中为不变量赋值

在序列化类中,不要使用构造函数为final变量赋值,如果赋值的话可能出现书中示例所给出的类版本变化时,序列化与反序列化的值不一致的问题。

十二、避免为final变量复杂赋值

final变量可以通过方法返回值进行赋值,不过要避免这种赋值方式。因为这样可能在类版本变化时,序列化与反序列化的值不一致的问题。
根本原因是final变量在以下三种情况下不会被重新赋值:

1. 通过构造函数为final变量赋值

2. 通过方法返回值为final变量赋值

3. final修饰的属性不是基本类型

十三、使用序列化类的私有方法巧秒解决部分属性持久化问题

在进行序列化时,有时部分属性不想序列化,此时会选择加上关键字transient,这在大多数情况下都可以,有时却无法满足需要,此时可以自实现序列化的readObject和writeObject方法,实现自定义的序列化逻辑。具体实例参考书籍建议14。

十四、break万万不可忘

在switch语句中,case后面执行的语句常常容易忽略break,造成不必要的错误,这个要注意。

十五、易变业务使用脚本语言编写

脚本语言灵活,便捷、简单,引入脚本语言会让Java更加强大。

十六、慎用动态编译

使用动态编译需要注意以下几点:
1. 在框架中谨慎使用。
2. 不要在要求高性能的项目中使用。
3. 动态编译需要考虑安全问题。
4. 记录动态编译过程。

十七、避免instanceof非预期结果

instanceof用来判断一个对象是否是一个类实例,其中要求左右操作数必需有继承关系或实现关系,不然编译会失败。

十八、断言绝对不是鸡肋

在防御式编程中经常会使用断言对环境和参数做出判断,避免程序因不当的输入或错误的环境而产生逻辑异常。
断言在下面两种情况下不可以使用: 1. 在对外公开的方法中:因为外部环境是不可控的,对外公开的方法应该是多做校验,而不是断言。 2. 在执行逻辑代码的情况下:因为assert的支持是可选的,所以不能在assert表达式中执行代码,这样可能因为环境的不同而是不同的逻辑。

十九、不要只替换一个类

 

在系统中经常会有常量类定义,这样在类编译时就会把常量值进行替换,如果常量类进行改变时,只编译常量类,而使用常量的类不重新编码,这样改动实际上算没有生效,从而可能引发一些问题。
例如在项目发布的时候发现某个常量类需要修改,这个时候重新改过后,为了省事,直接编译这个类,替换项目包中的class文件,再重新启动项目。可能就会出现上述其它引用到的常量值其实没有改动的问题。
所以在项目类文件有改动时,不要替换类文件,要重新编译整个项目再发布。

http://wdmcygah.iteye.com/blog/2184984

 

时间: 2024-10-28 22:02:41

如果常量类进行改变时,只编译常量类,而使用常量的类不重新编码,这样改动实际上算没有生效(转)的相关文章

运行时和编译时元编程—编译时元编程

原文链接    译文链接     译者:JackWang 运行时和编译时元编程 第二部分 2 编译时元编程 Groovy的编译时元编程支持编译时生成代码.这些变换(译者注:原文该专有名词是transformations,译者直译为变换,也许不准确.如果有知道准确翻译的读者恳请不吝赐教,待译者修正)叫做程序的抽象语法树(AST),在Groovy里,我们叫做AST变换.AST变换支持在编译过程中植入钩子,修改抽象语法树之后继续编译生成正常的字节码流.和运行时元编程相比,这种转换可以在类文件的修改可见

运行时和编译时元编程—运行时元编程

原文链接   译文链接   译者:JackWang 运行时和编译时元编程 第一部分 Groovy语言支持两种风格的元编程:运行时元编程和编译时元编程.第一种元编程支持在程序运行时修改类模型和程序行为,而第二种发生在编译时.两种元编程有各自的优缺点,在这一章节我们将详细讨论. 注:译者也是第一次接触Groovy,由于时间和水平有限(姑且让译者使用这个理由吧,对待知识本应该一丝不苟)部分专有名词可能翻译不准确甚至有误(读者阅读的过程中最好能参考原文),恳请读者不吝留言指出,谢谢! 1.运行时元编程

运行时和编译时元编程—运行时元编程(一)

运行时和编译时元编程 第一部分 Groovy语言支持两种风格的元编程:运行时元编程和编译时元编程.第一种元编程支持在程序运行时修改类模型和程序行为,而第二种发生在编译时.两种元编程有各自的优缺点,在这一章节我们将详细讨论. 注:译者也是第一次接触Groovy,由于时间和水平有限(姑且让译者使用这个理由吧,对待知识本应该一丝不苟)部分专有名词可能翻译不准确甚至有误(读者阅读的过程中最好能参考原文),恳请读者不吝留言指出,谢谢! 1.运行时元编程 通过运行时元编程,我们可以推迟运行时的分支决策(译者

AJAX页面参数相同时只返回缓存的内容的解决办法

AJAX页面参数相同时只返回缓存的内容的解决办法 常利用AJAX写一些页面无刷新的内容获取页面,这种方式很快捷也很方便,但其中有一个问题,就是如果两次提交的参数相同时,返回的内容只返回上次获取的内容,如果我们在第一次修改了参数,第二次再次调用却会发现页面根本没有改变.这样的情况是是为AJAX获取时先检查本机缓存,如果本机缓存已有相同内容,则不访问远端服务器.这样的操作倒是可以提高速度和减少服务器压力.但带来的弊端也是显而易见的. 为了解决这个问题.我们必须在获取页加上一个额外的参数.比较简单的方

java中有关定义常量int初始值时,怎样将出是最定义为最大

问题描述 java中有关定义常量int初始值时,怎样将出是最定义为最大 例如:int i=?;?处定义为最大值 解决方案 int i=Integer.MAX_VALUE; int a=Integer.MIN_VALUE; double b= Double.MAX_VALUE; double c= Double.MIN_VALUE; float d= Float.MAX_VALUE; float e=Float.MIN_VALUE;每个基础类型都有对应的类,有用请采纳 解决方案二: java中定义

ios-解码视频处理播放时只显示最后一帧图像,大家帮忙看看。。。

问题描述 解码视频处理播放时只显示最后一帧图像,大家帮忙看看... -(void)translate { int videoStream= -1; int frameFinished ; uint8_t *buf; avcodec_register_all(); avformat_network_init(); av_register_all() ; if( avformat_open_input(&pFormatCtx, [fLocalFileName UTF8String], NULL, N

flex 监听事件-flex中的datefield组件中点击下拉选择日期改变时派发事件

问题描述 flex中的datefield组件中点击下拉选择日期改变时派发事件 如题,我需要在选择日期时监听change事件,执行脚本,但是为什么每次会执行两次脚本. 怎么可以控制只在选择日期之后派发,而在点击时不派发. /** 添加监听事件 / this.addEventListener(CalendarLayoutChangeEvent.CHANGE, selectedChange); /* 对象更改处理函数 */ protected function selectedChange(event

运行时和编译时元编程—运行时元编程(二)

1.7.3 ExpandoMetaclass Groovy有一个特殊的MetaClass类叫做ExpandoMetaClass.它的特别之处在于支持动态添加或修改方法,构造函数,属性,甚至通过使用一个闭包语法来添加或修改静态方法. 这些特性测试场景将会非常使用,具体在测试指南将会说明. 在Groovy里,每一个java.lang.Class类都有一个特殊的metaClass属性,可以通过它拿到一个ExpandoMetaCalss实例.这个实例可以被用于添加方法或修改一个已经存在的方法的行为. 默

service-当实现调用的Activity或者fragment发生orientation改变时,服务器会停止吗?

问题描述 当实现调用的Activity或者fragment发生orientation改变时,服务器会停止吗? 当实现调用的Activity或者fragment发生orientation改变时,服务器会停止吗? 查了很多资料,都是当调用 Context.stopService()或者stopSelf()时服务器会停止. 就是说假设当Activity或者fragment发生orientation改变时,服务器不停止. 用startService()重写默认由bindService(Intent, S