备注:java 5以后enum是关键字
2 equals(obj)和hashCode()应该同时被重写
备注:特殊情况下我们要重写equals用来实现某些功能,但是同时必须要重写hashCode;如果obj1.equals(obj2) = true则obj1和obj2对应的内存地址应该相同,hashCode()返回的就是obj的对应的内存地址
3 equals(T obj)和compareTo(T obj)应该一起被重写
备注:严格要求来讲equals没有必定要和compareTo一起被重写,但是从正常的逻辑角度来说obj.equals(obj2) = true应该是obj.compareTo(obj2) = 0
备注:Error和他的子类代表异常的情况,例如内存溢出,通常只有java虚拟机(jvm)会接触到。
5使用object ==null替代object.equals(null)
备注:如果object为null使用object.equals(null)会抛出空指针异常
备注:如果只有2个分支,使用if else来进行逻辑处理
备注:switch(variable){
case 0:
myLabel:
result = 0 ;
break ;
case 1:…
default:…
}(错误的写法)
switch(variable){
case 0:…
case 1:…
}(正确的写法)
备注:匿名类代码长度过长,应该新建一个类(从代码可读性的角度)
备注:int[] foo();(正确的写法)int foo()[];(错误的写法)
备注:int[] arr ;(正确的写法)int arr[] ;(错误的写法)
备注:int a = 10 + 12 ; System.out.println(a);(正确的做法)
System.out.println(10 + 12) ;(错误的代码)
这样的好处是代码可读性强
备注:使用System.arrayCopy方法替代数组循环来拷贝数据2个数组之间的数据
备注:正常情况下代码不会抛出空指针异常,catch模块会隐藏原有的异常,导致其他更多微妙的错误
16在BigDecimal的构造方法中,避免使用数字的构造方法
备注:new BigDecimal(.1)这个不等于0.1其实是等于.1000000000000000055511151231257827021181583404541015625,因为0.1不等用二进制数来表示,建议使用new BigDecimal(“0.1”)来代替
备注:很多人猜测这是虚拟机抛出的异常,考虑使用IllegalArgumentException(非法参数异常)
备注:不要创建已经存在的整数,如BigInteger.ZERO, java 1.5以后的BigDecimal.ZERO ,BigDecimal.ONE
备注:避免创建布尔值,可以使用Boolean.TRUE /Boolean.FALSE或者Boolean.valueOf();
备注:如果一个对象为null ,调用这个对象的方法会出现空指针异常,有可能是因为你用||替代了&&
备注:boolean result = foo.equalsIgnoreCase(bar)(正确的写法);
boolean result = foo.toLowerCase().equlas(bar.toLowerCase());(错误的写法)
第二种写法效率比较低
备注:如果你想要得到某个集合类的数组,你需要传递一个指定类的数组参数到toArray方法中,否则你会得到类型不匹配的异常
备注:命名规范一般是大写字母开头,一般有camel命名规则
备注:public修饰变量不遵循java的封装原则
备注:在com.sun.*和sun.*的类是被认为某些方法的具体的实现,但是他们不是java api的一部分,当jdk的版本发生变化,可能会出现问题。
备注:保证资源(像Connection Statement ResultSet)在使用过后关闭
备注:if(condition1 ){ if(condition2) {…}}(错误的写法)
if(condtion1 && condition2) {…}(正确的写法)
30使用Collection.isEmpty()来判断Collection是否为空
备注:使用Collection.size()也有同样的效果,但是Collection.isEmpty()代码更易读。
备注:
//correct comment
int a = 1 ;(正确的注释)
int a = 1 ; // wrong comment(错误的注释)
备注:常量命名的正则表达式是^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$
34常量应该被申明为final static而不仅仅是final
备注:如果仅用final修饰变量,对于多个实例化的对象都会增加使用内存。
备注:调用可重写的构造方法产生对象,可能会存在风险。例如
public class SeniorClass(){
public Senior(){
return toString();
}
public String toString(){
return“Imseniorclass”;
}
}
public class Junior extends SeniorClass(){
public Junior(){
super();
name=”Junior”;
}
public toString(){
return name.toUperCase();
}
}
37逻辑控制语句,if, for, while和switch不应该嵌套太深
备注:嵌套的if, for,while,switch语句嵌套太深,可读性比较差,最多嵌套长度为3
备注:对于被用@Deprecated标注的代码,应该最终被删除
备注:public class foo(
@Deprecated
public void f1(){}(不正确的写法)
/**
* @Deprecated
*/
public void f2(){}(不正确的写法)
/**
*@Deprecated
*/
@Deprecated
public void f3(){}(正确的写法)
)
备注:重复的代码块应该被抽出来公用
备注:返回空的数组或者集合,而不是null可以降低复杂度,同时减少空指针异常的概率。
备注:如果finalizer()方法是空的,那么它没必要出现
备注:空的方法,循环,都应该被删除
备注:根据oracle的java官方文档,enumeration接口是复制的iterativeor接口,而且iterator接口中,增加了可供原则的remove方法,以及更短的方法名。
备注:异常意味着当错误出现的时候,应用的一个状态,用final修饰可以确保错误的异常状态不会被改变,例子如下
public class MyException extends Exception{
private int status ;
public MyException(String msg){
super(msg);
}
public int getStatus(){
return status ;
}
public void setStatus(int status ){
this.status = status;
}
}(错误的写法)
public class MyException extends Exception{
private final int status ;
public MyException(String msg){
super(msg);
this.status = status ;
}
public int getStatus(){
return status ;
}
}(正确的写法)
备注:try{…}catch(Exception e){ LOGGER.info(e)}…(错误的写法)
try{…}catch(Exception e){LOGGER.info(‘context’, e); }(正确的写法)
47异常类型不应该在catch块中使用“的instanceof”测试
备注:try{..
}catch(Exception e){
if(e instanceof IOException){…}
if(e instanceof NullPointerException){…}
}(错误的写法)
try{
…
}catch(IOException e){
…
}catch(NullPointerException e){
…
}(正确的写法)
备注:try {
} catch(Exception e){
}finally{
throw new Exception();
}(错误的写法)
try{
}catch(Exception e){
}finally{
//clean up
}(正确的写法)
备注:主动调用System.gc()或者Runtime.getRuntime().gc()不是个好主意,因为JVM的供应商,版本都未知
备注:复杂度最高为3
备注:正则表达式^[a-z][a-zA-Z0-9]*$
备注:FIXME标示通常是用来表示该处代码有bug,但是可能要稍后才进行处理,这条规则是要表示bug要持续追踪,并确保他不会被忽视
53通用的异常Error,RuntimeException,Throwable不应该向外抛出
备注:
public void foo() throws Throwable{ throw new Exception(“my message”) ; }(错误的写法)
public void foo(){ throw new MyException(“my message exception”)}(正确的写法)
备注:避免幂等操作,如以下例子
int x = 2 ; x = x ;(错误的写法)
备注:
public void foo() { if(true){doSomething(); }}(错误的写法)
public void foo() {doSomething(); }(正确的写法)
56 if else for while do语句应该使用大括号
备注:
if(condition) foo(); foo1();(错误的写法)
if(condition){
foo();
}
foo1();(正确的写法)
备注:避免在Stringbuffer中连接非文字或者使用append()方法
备注:避免通过实例化一个类来获取类例如Class c = new String().getClass() ;应该写成Class c = String.class;
备注:分支覆盖率要达到65%
备注:在jdk 1.5版本中使用new Integer()可能会导致内存分配问题,Integer.valueOf()内存分配更加合理
备注:^[A-Z][a-zA-Z0-9]*$
备注:IP地址 应该写在配置文件中
63应该用java的集合类如List代替特定的类的实现如LinkedList
备注:
public HashSet foo(){
return new HashSet();
}(错误的写法)
public Set foo(){
return new HashSet();
}(正确的写法)
备注:label在java里面并不经常使用,而且很多开发者并不清楚,他是如何工作的;
备注:
if(condition){
…
}(正确的写法)
if(condition)
{
…
}(错误的写法)
备注:^[a-z][a-zA-Z0-9]*$
备注:局部变量和类中的属性一样的话会导致代码可读性变差
class Foo{
int name = 12;
public Foo(int name){
this.name = name;
}(正确的写法)
public void doSth(){
int name = 123;
System.out.println(name);
}(错误的写法)
}
68 Logger应该要用private static final修饰,并且应该共享一个命名约定
备注:LOG(?:GER)?
备注:小写的”l”,很容易和1混淆
备注:
String[] names = new String[]{“a”,”b”};
for(inti = 0 ; i < names.length ; i++){
if(name[i]== null){
i = names.length ;(错误的写法)
break;(正确的写法)
}
}
71在循环体中不应该包含超过1个的continue或者break语句
备注:
for(inti = 0 ; i < 10 ; i++){
if(i% 2 == 0){
continue ;
}
if( i % 3 == 0){
continue ;
}
}(错误的写法)
for(inti = 0 ; i < 10 ; i++){
if(i % 2 == 0 || i % 3 == 0){
continue ;
}
}(正确的写法)
备注:^[a-z][a-zA-Z0-9]*$
备注:
public MyClass{
public String name =“12”;
public MyClass(String name){
name = name ;(错误的写法)
this.name = name ;(正确的写法)
}
public int add(int a , int b ){
a = a + b ;
return a ;(错误的写法)
return a + b ;(正确的写法)
}
}
备注:equals方法名应只用于重写object.equals(o),通过这样来防止混淆
备注:
public void foo(){
}(错误的写法)
public void foo(){
//do something
}(正确的写法)
备注:命名为hashCode有2种情况
1是个bug应该加上@Override的注解
2这不是个bug,但会使其他的开发人员混淆
备注:一个方法最多含有7个参数
备注:一个不能被实例化的类,而且没有任何静态方法不能被使用
备注:一般按照如下的顺序来修饰
public protected private abstract static final transient volatilesynchronizednative strictfp
备注:NCSS原则(没有注释的源码语句)
备注:for(int i = 0;i < 10 ; i++){ }(错误的写法)
for(inti = 0 ; i < 10 ; i++);(正确的写法)
备注:public voidevaluate(int operator){
switch(operator){
case ADD : {
int a = stack.pop();
int b = stack.pop();
int result = a + b ;
stack.push(result );
break ;
}
}
}(错误的写法)
public void evaluate(int operator){
switch(operator){
case ADD:
foo();
break;
}
}
private void foo(){
int a = stack.pop();
int b = stack.pop();
stack.push(a + b);
}
备注:
class Foo{
public Foo(){} ;
public int Foo(){ return 0 ; }(错误的写法)
public int foo(){return 1 ; }(正确的写法)
}
备注:非静态类初始化很少被使用,有时候能迷惑开发者。如以下代码
class MyClass{
private static final Map MY_MAP = new HashMap(){
{
put(“a”,”b”);
}
};(错误的写法)
private static final Map MY_MAP = ImmutableMap.of(“a”,”b”);(正确的写法)
}
备注:Object.finalize()是通过垃圾回收机制(GC)在对象不被引用的时候进行调用的
public void finalize(int someParam){
}(错误的写法)
public void someBetterName(int param){
}(正确的写法)
86当重写Object.finalize()方法时 应该用protected进行修饰
备注:一般而言Object.finalize()只有GC来调用,如果用public进行修饰,他意味着任意一个caller都能调用他
备注:
int myNumber =010 ;(错误的写法)
int myNumber = 8 ;(正确的写法)
备注:
@Override
public void doSth(){
super.doSth();
}(错误的代码)
@Override
public void doSth(){
super.doSth();
doOther();
}(正确的写法)
备注:^[a-z]+(\.[a-z][a-z0-9]*)*$
备注:
String a = new Integer(myInteger).toString()(错误的写法)
String a = Integer.toString(myInteger);(正确的写法)
备注:为了对调用者保持复杂度,方法不应该抛出1个以上的异常
public void delete() throws IOException, SQLException{
}(错误的代码)
public void delete() throws SomeLevelException{
}(正确的代码)
备注:
if(condition){
return true ;
}else{
return false ;
}(错误的写法)
return condition ;(正确的写法)
备注:在finally模块会强制执行所有语句,之前有可能在try或者catch模块应该返回的是error但是在finally模块返回的却是OK
94右括号应该和下一个next ,catch ,finally在同一行
备注:
if(con1){
}
else{
}(错误的写法)
if(con1){
}else{
}(正确的写法)
备注:
if(con1){
doSomething() ;}
else{ doOther() ; }(错误的写法)
if(con1){
doSomething();
}else{
doOther();
}(正确的写法)
备注:数组是直接存储的拷贝的对象,这个是用来防止将来元素发生变化时,数组中的元素也会发生变化
备注:没有必要在instanceof前面调用null判断,因为如果对象是null instanceof会返回false
备注:如果一个属性仅仅被一个方法引用,可以考虑使用局部变量来代替这个属性
备注:
a =“aa”; b =“bb”(错误的写法)
a =”aa”;
b =”bb”;(正确的写法)
备注:StringBuffer sb = new StringBuffer(‘c’);这个字符将要被转换成实例化StringBuffer的大小
备注:避免实例一个String,这不是必须的
备注:
public void foo(){
System.out.println(“action”);
System.out.println(“action”);
System.out.println(“action”);
}(错误的写法)
public void foo(){
String str =“action”;
System.out.println(str);
System.out.println(str);
System.out.println(str);
}(正确的写法)
备注:避免调用String的toString方法
104 String.valueOf()不应该直接加在一个String后面
备注:增加String.valueOf()到一个String后面 减少代码的可读性,传递到String.valueOf()的参数 应该直接加到String上面
备注:
String myString = null ;
System.out.println(“equals=”+ myString.equal(“foo”))(错误的写法)
String myString = null ;
System.out.println(“equals=”+”foo”.equals(myString));(正确的写法)
备注:String和其他的Object应该使用equals来进行比较
if(variable==“foo”) {}(错误的写法)
if(“foo”.equals(variable)){}(正确的写法)
107当重写Object.clone()方法的时候应该调用super.clone()
备注:根据Oracle的java文档中关于Object.clone()说明
1 x.clone() != x ;
2 x.clone().getClass() == x.getClass();
3 x.clone().equals(x);
4 super.clone()返回一个实例
5 super.clone()返回调用者的一个实例
6 object.clone()展现的是一个调用者的实例
class BaseClass implements Cloneable{
@Override
public Object clone() throws CloneNotSupportedException {
return new BaseClass() ;(错误的写法)
return super.clone();(正确的写法)
}
}
108 super.finalize()应该在实现object.finalize()后调用
备注:
protected void finalize(){
releaseResource() ;(错误的代码)
}
protected void finalize(){
releaseResource() ;
super.finalize();(正确的写法)
}
109 switch语句应该要添加结束语句(break , return , continue)
备注:switch(variable){
case 0 : doSomething ();(错误的写法阿)
case 1: doOther(); break ;(正确的写法)
default:
doSomthing();
}
备注:一般一个case最多5行
switch(variable){
case 0 :
System.out.println(“11”);
System.out.println(“11”);
System.out.println(“11”);
break;(正确的写法)
default:
System.out.println(“11”);
System.out.println(“11”);
System.out.println(“11”);
System.out.println(“11”);
System.out.println(“11”);
break;(错误的写法)
}
备注:
switch(state){
case 0
case 1:
System.out.println(“11”);
break;
}(错误的写法)
switch(state){
default:
System.out.println(“12”);
break;
case 0 :
System.out.println(“12”);
}(错误的写法)
switch(state){
case 0 :
System.out.println(“12”);
break ;
case 1:
break;
default:
System.out.println(“123”);
break;
}(正确的写法)
112同步类Vector Hashtable StringBuffer不应该被使用
备注:这些Vector Hashtable StringBuffer在早期的JAVA API中是被设计成线程安全的,但是在表现方面并不理想,即使是在单线程的情况下使用,现在可以使用不同步的方法来进行替代,使用ArrayList ,LinkedList代替Vector;HashMap替代Hashtable,StringBuilder替代StringBuffer
113 System.exit(…);Runtime.getRuntime().exit(…)不应该被调用
备注:调用System.exit(int status )和Runtime.getRuntime().exit(int status )会导致整个java虚拟机的关闭,要小心使用;例如他不应该由在一个J2EE容器内的应用进行调用。
114 System.out和System.err不应该像logger一样被使用
备注:logger必须满足的2个条件:用户能容易的得到日志;日志信息有一定的格式 确保用户能容易的浏览他们
备注:开发人员不应该因为要去阅读源码而去设置Tab的长度,tab应该被禁止。
备注:1变量定义2构造方法3函数
public class Foo (){
public static final int OPEN = 4 ;
private int field = 0 ;
public Foo(){}
public void doSomething(){}
}(正确的写法)
public class Foo (){
public Foo(){}
public void doSomething(){}
public static final int OPEN = 4 ;
private int field = 0 ;
}(错误的写法)
备注:根据java的官方文档Object.finalize()是被GC调用的。
备注:Object.finalize()没有明确的保证当一个对象的引用被除去的时候,finalize()方法会被立即的调用,其中间隔可能有几毫秒到几分钟,当一些系统资源需要处理一个对象,最好不要依赖这个异步机制来处理它们。
120 Thread.run()和Runable.run()不应该直接被调用
备注:使用Thread.run()和Runable.run()的目的是执行代码在一个独立的线程,直接调用这些方法并没有意义,因为这些处理代码是在当前的线程中。
Thread myThread = new Thread(runnable) ; myThread.run()(错误的写法)
Thread myThread = new Thread(runnable) ; myThread.start()(错误的写法)
备注:Throwable是所有Error和Exception的父类,Error是所有error的父类,不应该由应用进行捕获,只有Exception和他的子类才能被捕获
try{…} catch(Throwable t){}(错误的写法)
try{…} catch(Error e){}(错误的写法)
try{…} catch(Exception e){}(正确的写法)
122 Throw.printStackTrace()从来不应该被调用
备注:应该使用logger来代替
备注:抛出相同的异常;RuntimeException或者是他的子类;子类和父类
void foo() throws MyException , MyException{}(错误的写法)
void foo() throws Throwable , Excepion{}(错误的写法)
void foo() throws RuntimeException {}(错误的写法)
void foo() throws MyException{}(正确的写法)
void foo() throws Throwable {}(正确的写法)
void foo() {}(正确的写法)
备注:
try{
try{
doSomething();
}catch(RuntimeException r){
}
doSomething();
}catch(RuntimeException e){
}(错误的写法)
private void dedicatedMethod(){
try{
doSomething();
}catch(RuntimeException e){
}
}
try{
dedicatedMethod();
doSomething();
}catch(Exception e){
/** */
}(正确的写法)
备注:^[A-Z]$
class MyClass(){
void addAll(Collection c){}
}(错误的写法)
class MyClass(){
void addAll(Collection c){}
}(正确的写法)
备注:避免创建不必要的局部变量
备注:避免给一个方法或者构造函数传递参数,但是却不使用这个参数
备注:当检测到一个局部变量声明或分配,但未使用。应该删除这个变量
备注:在接口中的属性或方法含有默认的修饰符,变量默认的修饰符是public static final方法的修饰符是public abstract,嵌套在接口中的类或者是接口是public static
备注:在检查完object1 != null调用object1.equals(obj2)而不是obj2.equals(object1)
备注:当检测到一个私有字段声明分配一个值,但没有使用。
备注:没有被使用的私有方法,意味着dead code而dead code意味着没有存在的必要,也就是说应该被删除,这样能够减少代码量,也能减少引入bug
备注:使用Arrays.asList()将数组转化为List
备注:当检查单个字符的索引是,使用String.indexOf(char)来获得,这样速度快
备注:使用StringBuffer.length()来决定StringBuffer的长度,而不是使用StringBuffer.toString().equals()或者StringBuffer.toString().length()
备注:java文件的导入部分,应该由IDE自动生成而不是依靠人工生成的,没有使用的或者无用的导入会导致代码的可读性降低,应该把这些删除
备注:对一个不可变对象(BigDecimal或者BigInteger)进行操作,不会改变这个对象本身,操作的结果是一个全新的对象,因此忽视操作的结果是个错误
备注:使用括号有时候能引起误解,所以有的时候应该被删除。
return 3 ;(正确的写法)
return (x);(错误的写法)
return (x + 1);(错误的写法)
int x = (y/2 + 1) ; (错误的写法)
int y = ( 4 + x) *y(正确的写法)
备注:工具类意味着一群静态方法的结合,这意味着这个类并不需要被实例化,因次这不应该有公共的构造方法,java默认的给每个类添加一个公共的构造方法,因此至少一个非公用的构造方法应该添加到代码中
class StringUtils{
public static String add(String s1 , String s2){
return s1 + s2 ;
}
}(错误的写法)
class StringUtils{
private StringUtils(){
}
public static String add(String s1, String s2){
return s1 + s2 ;
}
}(正确的写法)