读改善java程序的151个建议(5)

来源:互联网 发布:excel2013无法粘贴数据 编辑:程序博客网 时间:2024/05/16 08:25
49.推荐覆写toString方法
相对于原始的,覆写后方便识别。

50.使用package-info 类为包服务
package-info是java中的一处特殊类,主要体现在三个方面:
(1)它不能随便被创建
(2)它服务的对象很特殊
(3)package-info不能有实现代码
作用表现在以下三个方面:
(1)声明友好类和包内访问常量
(2)为在包上标注注解提供便利
(3)提供包的整体注释说明
示例:
//PkgAnnotatioin.java
@Target(ElementType .PACKAGE)
@Retention(RetentionPolicy .RUNTIME)
public @interface PkgAnnotatioin {

}

//package-info.java
@PkgAnnotatioin
package PackageinfoTest;

 //这里是包类,声明一个包使用的公共类,强调的是包访问权限
class PkgClass {
        public void test (){
       }
}
//包常量,只运行包内访问,适用于分“包”开发
class PkgConst {
        static final String PACAKGE_CONST="ABC";
}

// client.java
public static void main(String[] args) {

               // TODO Auto-generated method stub
               String pkgNameString="PackageinfoTest" ;
               Package pkg=Package .getPackage(pkgNameString);
               Annotation[] annotations=pkg.getAnnotations ();
               for(Annotation an:annotations){
                      if(an instanceof PkgAnnotatioin ){
                            System.out.println ("Hi,i am here@" );
                            System.out.println (PkgConst.PACAKGE_CONST);
                           
                     }
              }
       }


51.不要主动进行垃圾回收
主动进行垃圾回收是一个非常危险的动作,因为System.gc要停止所有的响应(Stop the world) ,才能检查内存中是否有可回收的对象。
即使经常出现内存溢出也不要调用,内存溢出是可分析的,是可以查找出原因的,GC可不是一个好招数。

52.推荐使用String直接量赋值
利用字符串常量池(String Pool 或String Constant Pool 或String Literal Pool),它的创建机制是这样的:创建一个字符串时,首先检查池中是否有字面值相等的字符串,如果有,则不再创建,直接返回池中该对象的引用,若没有则创建之,然后放到池中,并返回创建对象的引用。
另:经过intern处理后的String与直接量是同一个对象。intern会检查当前的对象在对象池中是否有字面值相同的引用对象,如果有则返回池中对象,如果没有则放置到对象池中,并返回当前对象。
问题:对象放到池中会不会产生线程安全问题?java已经考虑到了,String类是一个不可变(Immutable)对象其实有两层意思:一是String是final类,不可继承,不可能产生一个String的子类;二是在String类提供的所有方法中,如果有String返回值,就会新建一个String对象,不可对原对象进行修改,这也就保证了原对象是不可改变的。
是不是要考虑垃圾回收问题?不用考虑了,虽然java的每个对象都保存在堆内存中,但是字符串池非常特殊,它在编译期已经决定了其存在jvm的常量池(Constant Pool),垃圾回收器是不会对它进行回收的

53.注意方法中传递的参数要求
本建议其实主要说的是在编写代码时,要注意java提供的方法参数说明。例子中提到的replaceAll方法中第一个参数是正则表达式,这在我们使用的时候,要特别注意,一些特殊的符号,在正则表达式中代表特殊的含议,不再是简单的字符了

54.正确使用String\StringBuffer\StringBuilder
String 类是不可改变的量,也就是创就不能再修改了,比如创建了一个“abc”这样的字符串,那么它在内存中永远都会是“abc”,即使想通过String提供的方法来尝试修改,也是要么创建一个新的字符串对象,要么返回自己;
StringBuffer是一个可变字符序列,它与String一样,在内存中保存的都是一个有序的字符序列(char类型的数组),不同点是StringBuffer对象的值是可改变的;
StringBuilder与StringBuffer基本相同,都是可变字符序列,不同点是:StringBuffer是线程字全的,StringBuilder是线程不安全的,通过查看两者的源码,就会发现在StringBuffer的方法前都有synchronized关键字,这也是StringBuffer在性能上远低于StringBuilder的原因。
在性能上,由于String类的操作大部份情况下都是产生新的String对象,而StringBuffer和StringBuilder只是一个字符数组的扩容而已,所能String的操作远慢于StringBuffer和StringBuilder的操作
不同的业务场景下使用不同的字符序列:
(1)使用String类的场景:在字符串不经常变化的场景中
(2)使用StringBuffer类的场景:在频繁进行字符串的运算(如拼接、替换、删除等),并且运行在多线程的环境中,如xml解析、http参数解析和封装等
(3)使用StringBuilder类的场景:在频繁进行字符串的运算(如拼接、替换、删除等),并且运行在单线程环境中,如Sql语句的拼装、json封装等

55.注意字符串的位置
eg:
public static void main(String[] args){
String str1=1+2+"apples";//结果是3apples
String str2="apples"+1+2;//结果是apples12
}
java中对加号的处理机制:在使用加号进行计算的表达式中,只要遇到String字符串,则所有的数据都会转换为String类型进行拼接,如果是原始数据,则直接拼接,如果是对象,则调用toString方法的返回值然后进行拼接。
注意:在“+”表达式,String字符串具有最高优先级

56.自由选择字符串拼接方法
对一个字符串进行拼接有三种方法:加号、concat方法及StringBuilder(或StringBuffer)的append方法
可以查看一个concat方法源码及append方法源码
在大量的测试时发现append的效率最高
虽然如此,但大多数情况下我们都可以使用加号(友好、方便),系统80%的性能消耗在20%的代码上(这才是真正关注的重点)

57.推荐在复杂字符串操作中使用正则表达式
正则表达式威力强大,但难以控制

58.强列建议使用UTF编码

59.对字符串排序持一种宽容的心态
英文字符串、中文字符串排序
中文中可以使用Collator 、或其他一些开源拼音排序...




0 0