Java十大低级错误

Java十大低级错误

 

为了规范大家的编程行为,借鉴前人的编程经验,避免低级错误的不断发生,特发布MDSP产品Java十大低级错误,供所有Java开发人员学习:

 

1、方法和变量命名随意而不规范,没有类注释、方法注释或注释不规范,代码修改后,不同步修改注释,导致注释与代码不符。

 

2、数据类不重载toString()方法(说明:编程规范要求“所有的数据类必须重载toString() 方法,返回该类有意义的内容”)。

 

3、对方法的调用不进行空指针判断而造成空指针异常。

 

4、数据库操作、IO操作的资源没有及时释放,数据库结果集和连接释放顺序不正确,或者使用没有必要的预处理。

 

5、循环体内包含了大量没有必要在循环中处理的语句,循环体内循环获取数据库连接,循环体内进行不必要的try-catch操作。(说明:编程规范中建议“不要在循环体内调用同步方法和使用 try-catch 块”)

 

6、嵌套使用try-catch,或者try-catch后面没有必要的finally操作(说明:数据库操作、IO操作等需要使用结束close()的对象必须在try -catch-finally 的finally中close())。

 

7、不对数组下标作范围校验。

 

8、equals操作时没有将常量放在equals操作符的左边(说明:字符串变量与常量比较时,先写常量,这样可以避免空指针异常)。

 

9、字符串转化为数字时没有做异常处理。

 

10、没有在异常分支记录日志导致问题定位困难。

 

 

代码案例(说明:所有样例都是错误的代码):

1、方法和变量命名随意而不规范,没有类注释、方法注释或注释不规范,代码修改后,不同步修改注释,导致注释与代码不符。

 

public class MethodName

{

//错误:没有类的注释

//错误:方法的注释不规范、方法名不规范

    public void a( int i )

    {     

//错误:变量名称太短

String b = "";    

 

//错误:变量名称太长,超过40个字符

String longVariableLongVariableLongVariableLongVariable= "";

}

 

    /**

     * <一句话功能简述>方法命名约定:应以小写字母开头、同时命名不应含有下划线字符。

     * <功能详细描述>

     * @param i

     * @see [类、类#方法、类#成员]

     */

    public void Check_Method( int i )

    {

        // 错误:方法名称不规范

//错误:变量名称不规范

String b = "";  

    }

 

    /**

    * <一句话功能简述>变量、方法名、类名、接口名避免出现美元字符$。

    * <功能详细描述>

    * @param i

    * @see [类、类#方法、类#成员]

    */

    public void Fo$o ()

// 错误:方法名称不规范     

}

 

    /**

     * <一句话功能简述>注意hashCode方法大小写。此规则用于推测作者可能是要实现hashCode方法,但大小写错了。

     * <功能详细描述>

     * @return

     * @see [类、类#方法、类#成员]

     */

    public int hashcode()

    {

        // 错误:方法名称不规范

int temp = 0;

        // oops,this probably was supposed to be hashCode

        return temp;

 

    }

 

    /**

     *

     * @param o 只有参数类型和返回值类型不一致,方法名equals完全相同(包括大小写也相同),推测可能是想实现equals方法。

     * @return

     */

    public int equals(Object o)

    {

        // 错误:方法名称不规范

// oops, thisprobably was supposed to be boolean equals

        int temp = 0;

        return temp;

    }

 

    /**

     * <一句话功能简述>只有参数类型和返回值类型不一致,方法名equals完全相同(包括大小写也相同),推测可能是想实现equals方法。

     * <功能详细描述>

     * @param s

     * @return

     * @see [类、类#方法、类#成员]

     */

    public booleanequals(String s)

    {

        // 错误:方法名称不规范

// oops, thisprobably was supposed to be equals(Object)

        return true;

    }

 

    /**

     * <一句话功能简述>'getX()'方法同时返回值又是 'boolean' ,则建议用'isX()'命名。checkParameterizedMethods属性用于决定是否对带参数的方法检测。

     * <功能详细描述>

     * @return

     * @see [类、类#方法、类#成员]

     */

    public boolean getFoo()

    {

        // 错误:方法名称不规范

// bad

        return true;

    }

 

}

 

 

2、数据类不重载toString()方法(说明:编程规范要求“所有的数据类必须重载toString() 方法,返回该类有意义的内容”)。

public classContent extendsBaseMetaData

{

   private String oldCID;

 

    private String cId;

 

    private String spId;

 

    private inttype;

 

private int serviceType;

.........................

    /**

     * 设置修改标识

     * @param update_flag修改标识

     */

    public voidsetUpdate_flag(String update_flag)

    {

        this.updateFlg= update_flag;

 

    }

    public voidsetVersion(String version)

    {

        this.version= version;

}

public StringtoString()   

    {

        //没有重载toString方法或者重载无意义的toString方法

return null;  

}

}

 

3、对方法的调用不进行空指针判断而造成空指针异常。

/**

 * <一句话功能简述>演示不进行空指针判断造成空指针异常

 * <功能详细描述>

 *

* @see  [相关类/方法]

 * @since  [产品/模块版本]

 */

public class NullPoint

{

 

    /**

     * <一句话功能简述>

     * <功能详细描述>

     * @return

     * @see [类、类#方法、类#成员]

     */

    public String returnNull()

    {

        Stringtemp = null;

        return temp;

    }

 

    public void checkNull()

    {

        String str1 = "aa";

 

        //错误:没有对returnNull()的值进行为空判断,会造成空指针

if (str1.equals(returnNull()))

        {

            str1 = returnNull();

        }

       print(str1);

 

    }

 

    public void print(String str)

    {

    }

}

 

 

 

4、数据库操作、IO操作的资源没有及时释放,数据库结果集和连接释放顺序不正确,或者使用没有必要的预处理。

/**

 * <一句话功能简述>该类用来演示没有释放资源的的错误

 * <功能详细描述>

 * @see  [相关类/方法]

 * @since  [产品/模块版本]

 */

public class ReleaseRes

{

    public void releaseDB ()

    {

        Connectionconn = null;

       APLResultSet rs = null;

        Stringsql= "";

        try

        {

            conn =DB.getConnection();

 

            rs =DB.query(sql);

            if (rs.next())

            {

                return rs.getString("currentdate");

            }

            else

            {

                returnDateTool.getCurrentDate(pattern);

            }

            Conn.close(); 

//错误:连接没有在finally正确释放,会出现异常时导致在运行一段时间后,系统由于连接池满载而崩溃。

        }

        catch (DBException e)

        {

           ...................

        }

        //错误:资源APLResultSet没有正确释放  

 }

     /**

     * <一句话功能简述>

     * <功能详细描述>

     * @param file

     * @see [类、类#方法、类#成员]

     */

    public void releaseIO (Filefile)

    {

       StringBuffer sb = null;

       BufferedReader in = null;

        try

        {

            in = new BufferedReader(new FileReader(file));

 

            sb = new StringBuffer();

            for (String line; (line = in.readLine()) != null;)

            {

               sb.append(line + "\r\n");

            }

        }

        catch (IOException ex)

        {

            Throwex;

        }

         //错误:IO资源没有正确释放,需要在finally中释放资源

   }

 

 

 

 

5、循环体内包含了大量没有必要在循环中处理的语句,循环体内循环获取数据库连接,循环体内进行不必要的try-catch操作。(说明:编程规范中建议“不要在循环体内调用同步方法和使用 try-catch 块”)

 /**

 * <一句话功能简述>该类用来演示循环中的错误

 * <功能详细描述>

 * @see  [相关类/方法]

 * @since  [产品/模块版本]

 */

public class CheckCycle

{

    public void cycleInfo()

    {

        String[] Str = null;

 

        //获取各个部件的通知地址

        Str =outNotify.getResult();

       StringBuffer sb = null;

       BufferedReader in = null;

 

        Connectionconn = null;

       APLResultSet rs = null;

        Stringsql= "";

        File file= null

 

        for (int i = 0; i <Str.length; i++)

        {

           //错误:判断完全可以在for外部进行而不是在内内部。

           if( null != Str)

           {

              System.out.print(Str[i]);

           }

 

          //错误:不要在循环中获取数据库连接。

           conn =DB.getConnection();

 

           //错误:循环体内进行无必要的try-catch操作,完全可以放在循环外边。

           try

           {

               //错误:不要在循环中获取IO连接。

               in= new BufferedReader(new FileReader(file));

 

               sb= new StringBuffer();

              

           }

           catch (IOException ex)

           {

              Throw ex;

           }

        }

    }

}

 

6、嵌套使用try-catch,或者try-catch后面没有必要的finally操作(说明:数据库操作、IO操作等需要使用结束close()的对象必须在try -catch-finally 的finally中close())。

/**

 * <一句话功能简述>演示嵌套循环的错误

 * <功能详细描述>

 * @see  [相关类/方法]

 * @since  [产品/模块版本]

 */

public class NestingTry

{

    /**

     * <一句话功能简述>

     * <功能详细描述>

     * @see [类、类#方法、类#成员]

     */

    public void checkTry()

    {

       StringBuffer sb = null;

       BufferedReader in = null;

File file = null

        try

        {

            initFtpClient(this.ftpClient,getFtpServConfig());

            // 把绝对路径加入到文件中

            String[] absoluteFiles null;

 

            //错误:完全没有必要在内容进行异常处理,而应该将异常处理放在try块后面进行处理。

            try

            {

                absoluteFiles =addAbsolutePath(this.ftpClient, files);

            }

            Catch(IOException ex)

            {

                Throw ex;

            }

File file = null

            in = new BufferedReader(newFileReader(file));

            sb = new StringBuffer();

        }

        catch (Exception e)

        {

            throw newFtpOperationsException(FtpConst.Ftp_Operations_Del_Error,

                    "IOException wheninvoking deleteFiles method", e);

        }

         //错误:IO资源没有正确释放,必须有finally进行释放资源

    }

}

 

7、不对数组下标作范围校验。

/**

 * <一句话功能简述>该类用来演示数据下标越界

 * <功能详细描述>

 * @see  [相关类/方法]

 * @since  [产品/模块版本]

 */

public class ArrayOver

{

    public void checkArray()

    {

        //获取一个数组对象

        String[] cIds =ContentService.queryByName(name);

       

        if(null != cIds)

        {

           //错误:只是考虑到cids有可能为null的情况,但是cids完全有可能是个0长度的数组,因此cIds[0]有可能数组下标越界。

            Stringcid=cIds[0];

       

        }

 

    }

}

 

 

8、equals操作时没有将常量放在equals操作符的左边(说明:字符串变量与常量比较时,先写常量,这样可以避免空指针异常)。

     /**

     * 定义常量

     */

    public static final String SP_NAME = "SPNAME";

 

    /**

     * <一句话功能简述>常量比较

     * <功能详细描述>

     * @see [类、类#方法、类#成员]

     */

    public void equalsConst()

    {

        Stringtemp = null;

 

        //错误;//在temp为null的情况下,此时会导致意想不到的异常抛出,如果将常量放在左边,就不会有这种问题。

        if(temp.equals(SP_NAME))

        {

           temp = SP_NAME + "AA";

 

        }

    }

 

9、字符串转化为数字时没有做异常处理。

    /**

     * <一句话功能简述>字符传传唤成数字

     * <功能详细描述>

     * @see [类、类#方法、类#成员]

     */

    public void switchStr()

    {

        String temp = "123a";

 

        //错误:对字符串转换为数字没有进行任何异常处理。可能抛出未知异常。

        if(Integer.parseInt(temp)== 123)

        {

           //......

        }

    }

 

10、没有在异常分支记录日志导致问题定位困难。

     /**

     * 根据objectId删除业务信息

     *

     * @param id 业务objectId

     * @throws IllegalServiceStatusException 非法业务状态异常

     * @see [类、类#方法、类#成员]

     */     

public void deleteService(String id)

        throwsIllegalServiceStatusException

    {

        log.enterMethodDebugLog(new Object[][] {{"id", id}});

        MdspTServiceinfo serviceInfo =getMdspServiceByObjectId(id);

        if (null == serviceInfo)

        {

             return;

             //错误:异常分支没有记录日志,导致问题定位困难。

        }

        ........

       

    }

        

 

 


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值