资源描述
Java开发规范Aostar & YinHai开发管理文件编号: 文件名称:Java开发规范版 本 号日期:项目名称项目编号:项目负责人立项日期:修订历史记录日期版本号作者说明2009-6-25V1.0王流一目 录第1章序言3第2章java一般性研发规范52.1代码格式52.1.1包、类、方法的命名规范:52.1.2方法的命名应注意避免与java中具有特殊意义的名称例如equals,hashCode,clone,finalizer等冲突72.1.3Java bean中取得boolean类型的属性值必须使用is*形式命名82.1.4if,else,while,for等必须使用92.1.5类必须包含在包里,禁止出现无包的类102.1.6类和方法必须拥有注释,注释量占总体代码25%以上,类头部,以及方法头部的注释应符合javadoc标准。102.2基本语法112.2.1不能随意捕捉异常,原则上谁捕捉谁处理112.2.2if,while,try,finally,switch , synchronized , static instantiation 里面应有相应的逻辑处理,不能为空。122.2.3在处理循环中,不能在程序中人为的改变步长。132.2.4将简单类型int,short,float,double等转化成字符串时,需使用其对应类的toString方法。132.2.5javaBean中hashCode,以及equals方法必须同时override。142.2.6懒式方式创建对象:不能采用双检查惯用法172.2.7不能在finally中返回值。182.2.8Boolean实例化时,应用使用Boolean.valueOf,Boolean.TRUE,Boolean.FALSE。192.2.9Integer,Byte,Short,Long等实例化时,应用使用valueOf192.2.10对于多个if语句嵌套的情况下能够整合尽量整合。202.2.11override function,不能只有super.function语句,否则视为无效代码202.2.12Collection.toArray的注意事项。212.2.13对于BigDecimal方法,应避免使用float值,double值进行创建,应使用字符串形式创建。212.2.14String,BigDecimal,BigInteger等值类型调用replace,add等方法的注意事项。222.2.15需要注意的引起NullException的语句。222.2.16ResultSet使用next时,需要判断是否具有记录再进行一下步操作。242.2.17字符串使用相应的规则。252.2.18禁止直接调用System.gc(),System.getRuntime().gc(),System.runFinalization()。262.2.19finalize相应的规则。272.2.20禁止在代码中使用System.out,ex.printStackTrace打印日志。272.2.21系统资源释放(谁创建的,谁关闭)282.2.22使用Clone时相应的规则。322.2.23java Bean类必须实现Serialize接口。322.2.24比较对象相等应使用equals,而不是=。322.2.25Array数组拷贝应使用System.arrayCopy。332.3耦合性以及设计332.3.1switch语句必须包含default标签。332.3.2精简boolean表达式以及boolean返回值。342.3.3在方法实现中应避免对输入的值参进行改变。352.3.4在创建方法中,应避免调用被override的方法352.3.5public static常量属性必须final。362.3.6Abstract 类必须含有abstract方法。372.3.7接口依赖性。372.4代码质量因素382.4.1Class代码行数限制382.4.2函数代码质量38第3章java安全性检查规范403.1跨站脚本XSS403.2违反信任边界规则(Trust Boundary Violation)413.3不安全的反射(Unsafe Reflection)423.4SQL 注入(SQL Injection)433.5系统信息泄露(System Information Leakage)443.6资源注入(resource injection)45第1章 序言本规范的目的在于:建立一个可行可操作的编程标准、约定和指南,以规范公司java代码研发工作。2009年为公司的质量年,为了提高公司研发能力,该规范的制定是为了规范java代码开发,提高java开发质量,从代码的层面规范并提高java项目的研发水平。该规范由运营中心技术小组制定,运营中心技术小组将结合PMD检查工具以及相应的检查工具,组织技术监控人员对重点项目以及新的java项目定期检查,对代码质量进行评估,对代码质量较差限期整改,并报运营中心备案作为项目考核依据。本规范适用于2009年公司java代码研发规范。本规范的内容包括两个方面:java开发一般规范,以及java代码开发安全性规范。Java代码开发一般规范主要从java基本语法,代码格式,耦合性以及设计方面,以及代码质量因子等进行描述;java代码开发安全性规范主要从sql注入,资源注入,跨站脚步,安全边界违例,系统信息泄露进行描述。为了方便并配合PMD检查工具等相应检查工具,方便开发者针对违规代码进行调整,本规范中java一般开发规范描述形式将结合PMD,并提供示例代码,其形式如下:n 规范描述:n PMD规则名称:n PMD级别(注1):n 违规示例代码:n 合法示例代码:本规范中java安全开发规范部分将结合具体项目,对出现安全隐患的代码进行分析,以及相应的解决办法和思路上进行分析,其具体格式如下:n 风险及危害:n 应对措施:n 非安全代码示例n 安全代码示例本规范解释权归运营中心技术小组,属于运营中心为了提供公司研发水平以及质量的一系列措施中的一部分,在后续的版本中将根据具体需要进行修改以及调整。 注1:PMD级别分为5级 Error high 必须修改 Error 不修改的项需要进行说明 Warning high 代码中该项每千行代码不能多于2%; Warning 参考 Information 参考注2:对于Error级别需要项目组通过以下文字说明:文件名代码行数触发PMD规则不修改原因技术小组审核意见技术小组审核后给出相应的整改意见,对于有争议的问题,可直接与运营中心技术小组领导成员沟通。第2章 java一般性研发规范2.1 代码格式2.1.1 包、类、方法的命名规范:n 规范描述:包,类,方法命名只能为27个英文字符以及数字,不能包括特殊字符例如-,_,$等;包命名,首字符必须小写;类命名,首字符必须大写;方法命名,首字符必须小写;常量命名,必须全部大写;变量,以及属性命名,首字符必须小写;在类中非创建方法其命名应避免与类命一致;在类中属性的命名应避免与类命一致;在同一类中属新命名应避免与方法命名一致;在方法中命名临时变量时应避免与方法的参数名一致;n PMD规则名称:AvoidDollarSignsPackageCaseClassNamingConventionsMethodNamingConventionsSuspiciousConstantFieldNameVariableNamingConventionsMethodWithSameNameAsEnclosingClassAvoidFieldNameMatchingTypeNameMisleadingVariableNamen 规则级别:Error Highwarn Highwarn Highwarn Highwarn HighError HighError HighError Highn 违规示例代码:1、 常量、变量命名public static final int my_num = 0; /常量应大写public String MyTest = ; /变量命名,首字符小写DataModule DMTest = new DataModule();/变量命名,首字符小写2、 方法命名public class Foo public void FooStuff() 3、 类命名:首字符应大写public class foo 4、 非法使用特殊字符命名 public class Fo$o / yikes! 5、 非创建方法命名应避免与类名一致public class MyClass / this is bad because it is a method public void MyClass() / this is OK because it is a constructor public MyClass() 6、 方法中临时变量的命名应避免与其参数一致:public void bar(String m_baz) / Bad int m_boz = 42; / Bad7、 在类中属性的命名应避免与类命一致: public class Foo extends Bar / Theres probably a better name for foo int foo;8、 在同一类中属性命名应避免与方法命名一致:public class Foo Object bar;/ bar is data or an action or both?void bar() n 合法代码示例: 1、 常量、变量命名:public static final int MY_NUM = 0; /public String myTest = ;DataModule dmTest = new DataModule();2、 方法命名:首字符应小写public class Foo public void fooStuff() 3、 类命名:首字符应大写public class Foo 2.1.2 方法的命名应注意避免与java中具有特殊意义的名称例如equals,hashCode,clone,finalizer等冲突n 规范描述:在java中某些方法是具有特殊意义的,例如boolean equals(Object o)是比较两个对象是否相;int hashCode()取得hash值,主要用于hash表;Object clone()用于复制对象;void finalizer()用于该类实例化的对象释放时系统调用释放该对象使用的资源。这些方法具有固定的形参格式,固定的返回值,不能被其他形式或者用于其他方面的方法override,否则将降低代码可读性,并为代码维护带来隐患。n PMD规则名称: SuspiciousEqualsMethodNameSuspiciousHashcodeMethodName;FinalizeOverloaded;BooleanGetMethodName;n 规则级别:Error HighError HighError HighError Highn 违规示例代码:1、 可疑的equals方法命名public class Foo public int equals(Object o) / oops, this probably was supposed to be boolean equals public boolean equals(String s) / oops, this probably was supposed to be equals(Object) 2、 可疑的hashCode命名public class Foo public int hashCode(int value) / oops, this probably was supposed to be hashCode n 合法代码示例: 1、 正确的equals方法命名public class Foo public boolean equals(Object o) / oops, this probably was supposed to be boolean equals 2、 正确的hashCode命名public class Foo public int hashCode() / oops, this probably was supposed to be hashCode 注:一般来说override hashCode方法为了避免键值冲突,提高hash表的查询效率,可采用37乘法原则,例如某javabean中包含两个关键属性str1,str2,str3该关键属性不能为空,这其hash值按以下算法获得:str1.hashCode()+str2.hashCode()*37+str3.hashCode()*37*37。2.1.3 Java bean中取得boolean类型的属性值必须使用is*形式命名n 规范描述:对于java bean来说,get*是取得该bean的属性值,set*为设置该bean的属性值,is*是获得该bean中为boolean类型的属性值,这些方法对java bean来说是具有特殊意义,如果命名不规范将导致在使用java bean内置方法时出现取值,或者设值不成功。n PMD规则名称: BooleanGetMethodNamen 规则级别:Error Highn 违规示例代码:public boolean getFoo(); / badn 合法代码示例: public boolean isFoo(); / ok2.1.4 if,else,while,for等必须使用n 规范描述:If,else,while,for等分支循环语句,必须使用将业务处理逻辑包含在内,这样可大大提高代码可读性,有利于后续代码维护。n PMD规则名称: IfStmtsMustUseBraces WhileLoopsMustUseBraces IfElseStmtsMustUseBraces ForLoopsMustUseBracesn 规则级别:warn Highn 违规示例代码:1、 if语句违例代码if (foo) x+;2、 else语句违例代码 if (foo) x+ else x-;3、while语句违例代码 while(x100) x+;4、 for语句违例代码for(int i=0;i10;i+) x+;n 合法代码示例: 1、 if语句if (foo) x+;2、 else语句 if (foo)x+else x-;3、while语句 while(x100) x+;5、 for语句for(int i=0;i10;i+) x+;2.1.5 类必须包含在包里,禁止出现无包的类n 规范描述:包是java中类所在命名空间,用于类载入时,虚拟机快速定位并查找该类;如果一个无包类,在类载入时,耗时较多,并且很可能无法找到该类。n PMD规则名称: NoPackagen 规则级别:error High2.1.6 类和方法必须拥有注释,注释量占总体代码25%以上,类头部,以及方法头部的注释应符合javadoc标准。n 规范描述:注释多少是评价代码质量好坏的一个标准,25%是符合国际上对java注释的标准;对于类头部注释,方法头部注释符合javadoc标准,可java工具自动根据源码生成相应的java帮助文档。对于类头部注释需要包含以下信息:该类的主用功能,作者,以及创建时间等信息;对于方法头部注释需要包含以下信息:该方法的主要功能,以及参数类型含义,返回值类型含义等等。n 合法代码注释示例1、 类头部注释规范/* * 实时数据文件解析:读取实时数据文件,对其内容进行解析,生成符合格式以及标准单位的数据集合 * author wangliuyi * version 1.0 * since 2009-05-15*/ public class DataFileParse2、 方法头部注释规范/* 判断该时间是否在统计时区里面* param time long 从实时采集文件中提取的时间,该时间为格林威治时间,单位为毫秒* return boolean true:表示该时间在合法的时间区内 false:表示该时间不合法*/public boolean checkStatTimeZone(long time)3、 属性以及方法内部的注释通过“/”注释public class GeneralStat implements IStat/解析数据格式的分隔符号private String separator = ,;/开始统计序号private int startNum = 1;2.2 基本语法2.2.1 不能随意捕捉异常,原则上谁捕捉谁处理n 规范描述:Java程序运行过程中产生异常,意味着有错误产生,捕捉该异常,就需要对该异常进行处理:例如记录日志,事务回滚等,如果仅捕获而不处理,人为的屏蔽异常,调用该函数,可能为调用者带来困惑,调用者极可能认为该方法正常运行而做出错误的判断。一般来说,异常处理机制属于应用程序总体框架的一部分,一个良好的异常处理机制可以避免系统产生的一些不可预测的结果,并提高代码可读性,可维护性,从而提高代码的质量。本规则要对异常处理进行检查,对一些捕捉后不处理,或者直接将该异常抛出等进行预警。n PMD规则名称: EmptyCatchBlockn 规则级别:Warn Highn 违规示例代码:public void doSomething() try doSomething; catch (IOException ioe) / 获取异常后没有做任何处理 n 合法代码示例: public static int parseInt(String value, int defaultValue)if (isNull(value)return defaultValue;tryreturn Integer.parseInt(value.trim();catch (Exception ex) /记录日志 Log.warn(“转换异常”,ex); /异常后返回缺省值return defaultValue;2.2.2 if,while,try,finally,switch , synchronized , static instantiation 里面应有相应的逻辑处理,不能为空。n 规范描述:在if,while,try,finally,switch,synchronized,static Initializer中处理逻辑部分如果为空,很可能这段代码无任何作用,是段废弃的代码,这段代码的存在不仅对代码维护带来疑惑,降低了整体的代码质量。n PMD规则名称:EmptyIfStmtEmptyWhileStmtEmptyTryBlockEmptyFinallyBlock EmptySwitchStatementsEmptySynchronizedBlockEmptyStaticInitializern 规则级别:Warn Highn 违规示例代码:1. if语句中为空if (foo) 2. while语句中为空 while(x100) 3. try,finally中为空tryfinally4. switch中为空switch(value)5. synchronized中为空synchronized(this)6. static Initializer为空static2.2.3 在处理循环中,不能在程序中人为的改变步长。n 规范描述:在循环中对步长变量人为的改变,很有可能丧失对步长的控制,导致运行时出现一些不可预测的结果。该规则是限制开发者对这种场景的使用,毕竟步长在多个地方改变,开发者很容易没有考虑全面,导致在特殊情况下出错。n PMD规则名称:JumbledIncrementer n 规则级别:Errorn 违规示例代码:1. 上述代码会陷入死循环 public void foo() for (int i = 0; i 10; i+) for (int k = 0; k 0;判空: string=null|string.length()=0;执行类似equals语句:a!=null&a.equals(b);禁止使用equals(null)方式n PMD规则名称:MisplacedNullCheckUnusedNullCheckInEqualsBrokenNullCheck n 规则级别:Error Highn 违规示例代码:1、 空指针检查错位if (a.equals(baz) & a != null) ;if (a.equals(baz) | a = null) ;2、 无用的空指针检查if (a!=null & b.equals(a) / 该处虽然对a对象进行了检查,但没有对b进行检查/whatever3、 常见的判空,判非空代码编写上的错误/判非空,却使用了|if (string!=null | !string.equals()return string;/判空却用了& if (string=null & string.equals()return string;4、 比较对象是否为空,使用了equalsstr.equals(null)n 合法代码示例:1、 空指针检查应放在前面if (a != null & a.equals(baz) ;if (a = null |a.equals(baz) ;2、 已检查的对象作为调用者if (a!=null & a.equals(method1) / 该处虽然对a对象进行了检查,但没有对mothod1进行检查/whatever3、 常见的判空,判非空代码编写上的错误/判非空用了&if (string!=null & !string.equals()return string;/判空用| if (string=null | string.equals()return string;4、 比较对象是否为空,使用了=If(str=null)2.2.16 ResultSet使用next时,需要判断是否具有记录再进行一下步操作。n 规范描述:java对数据库进行查询操作,取得结果集合ResultSet对象,使用next,让游标定位到下一行,下一行不存在时,next()返回false,该规则这是强制对下一行是否用记录进行判断,根据结果进行后续操作。n PMD规则名称:CheckResultSet n 规则级别:Error Highn 违规示例代码:Statement stat = conn.createStatement();ResultSet rst = stat.executeQuery(SELECT name FROM person);rst.next(); / what if it returns a false ?String firstName = rst.getString(1);n 合法代码示例:/ This is appropriate.Statement stat = conn.createStatement();ResultSet rst = stat.executeQuery(SELECT name FROM person);if (rst.next() String firstName = rst.getString(1);else / here you deal with the error ( at least log it)2.2.17 字符串使用相应的规则。n 规范描述:字符串是应用服务器创建最多的对象之一,对字符串操作按照合适的规则进行编写,会极大增加应用服务整体性能,以下是字符串操作相应的规则:字符串比较需要使用equals,而不是=,!=,因为=只是对同一引用的对象比较认为相同,而不比较对象里内容是否相等;使用StringBuffer代替string+string+string进行字符串相加,n个字符相加,如果直接用“+“号,会新产生n-1个StringBuffer对象,以及n-1个String对象,而用StringBuffer只会产生1个String,1个StringBuffer对象。使用equalsIgnoreCase() 替代 toUpperCase/toLowerCase().equals(),这样减少一个对象的创建,效率更高。使用StringBuffer.length()替代StringBuffer.toString().length(),这样减少一个对象的创建,效率更高。对于String对象禁止使用string.toString(),本身是String对象,这样调用效率低下,而且由于string没有判空,很可能导致空异常的风险。n PMD规则名称:UseEqualsToCompareStringsUseStringBufferLengthUnnecessaryCaseChangeUseStringBufferLenStringToString n 规则级别:Error Highn 违规示例代码:1、 字符串比较if(str1=str2) 2、 字符串相加String str=str1+str2+str3+str4;3、 大小写不敏感字符串比较str1.toUpperCase().equals(str2.toUpperCase();4、 取StringBuffer
展开阅读全文