Java 项目Building之后发现的Blocker和Critical

11 篇文章 0 订阅

     刚来公司老大吩咐我做Code Quality. 需要做到所有的项目的Blocker 和 Critical 的数量为0.当时我觉得很难,因为我已经没有做个Java项目,所以面对这些Issue有点害怕,毕竟我的改动会造成整个项目的问题。当时就连一个空格老大都严格的要求我,格式有一点点的错误老大就回reject的提交的代码。。。。。。一把辛酸泪啊!想想刚来的时候神马Jekins,神马Jira,神马Sonar简直了!!!

    我遇到Issue主要包括:

              1.Badpractice        定义 equals 却没有定义 hashCode
              2.Dodgy                  从实例方法里直接修改类变量,即 static 属性
              3.Performance      HashMap entrySet iterator  insead of keySet   iterator
              4.Correctness       空 指针被引用,或者没有检查指针是否为 null

    我依稀记得我当时做的第一个Blocker就是,项目中出现最多的问题    “Catch Exception instead of Throwable”  这是一个很普遍的错误。

       catch (Exception t) {

       Log.logError(getClass(),"Error Collecting Metrics", t);

  }

      catch(Throwablet){

       Log.logError(getClass(),"Error Collecting Metrics", t);

  }

 原因: Throwable 包括了Exception 和 error ,catch 的只是Exception, error 是不需要的catch的,如果catch有可能造成很严重的后果。

2 . Use a logger to log  this exception

        

`        This exceptionwill often get logged in a separate file (System.err) making debugging more complex than itneeds

3 .“equals(Object obj )” should be overridden along with the compareTo (T obj )” method

       “equals(Object obj)”  and  “hashCode()“  shouldbe overridden in pairsBadPractice

     这两个问题其实很深奥,必须了解hashMap的存储机制,后续我会详细解释,记住一点hashCode相同equals不一定相同。

下面介绍的都是Critical的问题, Critical是

1.Method may fail to close stream

try {

  InputStreaminputStream =null;

  inputStream= new FileInputStream(downloadFile);

  byte[]buffer = new byte[BUFFER_SIZE];

  intbytesRead =-1;

  while((bytesRead= inputStream.read(buffer))!= -1) {

  output.write(buffer,0, bytesRead);

  }

} catch(Exception e) {

  thrownew WebApplicationException(e);

}


try (InputStreaminput = newFileInputStream(downloadFile)){

  byte[]buffer = new byte[BUFFER_SIZE];

  intbytesRead =-1;

  while ((bytesRead= input.read(buffer))!= -1) {

  output.write(buffer,0, bytesRead);

            }

}catch (Exception e) {

        throw new WebApplicationException(e);

}


如果把stream在try的括号里面初始化就可以保证stream最后一定会被close


2.Equality tests should not be made withfloating point values

  if (OPEN_FILE_COUNT== 0.00 || CONFIG_VALUE == 0.00)

  if (OPEN_FILE_COUNT== 0L || CONFIG_VALUE == 0L)

原因:计算机表示实数的精度问题

3 . makes inefficient use of keySet iterator instead of entrySet iterator

for(Integer index : this.clients.keySet()){

  Zclientc = this.clients.get(index);

    Map<Integer,ZClient> mapSet= this.clients; 

   for (Map.Entry<Integer,ZClient>entry : mapSet.entrySet()){

  Integerindex = entry.getKey();

  ZClientc = entry.getValue();

原因:提高效率,因为EntrySet 会比keySet访问的次数减少一次。

4.In J2EE getClassLoader () might not work as expected. UseThread currentThread () getContextClassLoader ()  instead.

     在动态加载资源的时候如果使用class.getClassLoader(),可能会导致和当前线程所运行的类和加载器不一致

这个问题没有实质性的理解。。。。。。。


5.Synchronize this lazy initialization of ' streamInstance

        private staticStreamDatastreamInstance= null;

    public static StreamDatagetStreamInstance(){

           if (streamInstance== null) {

         streamInstance= new StreamData();

            }

             return streamInstance;

       }

       privatestatic StreamDatastreamInstance= new StreamData();

       publicstatic StreamDatagetStreamInstance(){

                return streamInstance;

      }

后续将在单例模式中详细的解释

6 . Possible null pointer dereference of null ( Correctness )

     if (dir.isDirectory()){

            String[]children = dir.list();

            for (Stringchild : children) {

                  return traverse(newFile(dir,child));

           }

     

   

    if (dir.isDirectory()){

          String[]children = dir.list();

          if(children !=null){

                 for (Stringchild : children) {

                        return traverse(newFile(dir,child));

                 }

          }

   }

很简单不解释


7. Use"object == null" instead of " object.equals (null)" to test for nullity toprevent null pointer exceptions

  if (null!= reqHead&& !reqHead.equals(null))

  if (null!= reqHead)

8 . Returning ' ruleName ' may exposean internal array

   代码使一个指向外部多个对象的引用指向了一个内部对象存储地址

   privateString[] ruleName;

   publicString[] getName() {

                String[]temp = ruleName;

            return temp;

  }

  public void setName(String[]name) {

           String[] temp = name;

           this.ruleName= temp;

  }

9. Useless Operation On Immutable

           String是一个不可变类,调用String上的任何操作都会返回新的String对象,虽然String是一个class,但实际上对它的任何操作都可以把它看成基本数据类型,比如s.trim方法是不会改变s值。

  Stringtext = null;

   while ((text = reader.readLine())!= null) {

    lineNumber++;

    text.trim();

text = text.trim();

10. Method invokes inefficient new String(String) constructor( Performance )

  Integer portNumber= null;

  if (port!= null) {

  portNumber= new Integer((int)port.intValue());}

 

     portNumber= Integer.valueOf(port.intValue());

11. Callto equals() comparing different types(Correctness)

      if (disabled.equals(true)){

  log.info("NucleonExtension Framework is disabled...");

  return;

    }

 

     if (disabled.equals("true"))

12.BUG : Write to static field frominstance method
BUG 描述: This instance method writes to a staticfield. This is tricky to get correct if multiple instances are beingmanipulated, and generally bad practice. (实例方法直接写静态变量。)
问题原因: sInstance 是类的静态成员变量,非静态 方法直接 对其赋值,非静态方法是与对象相关联的,当多个对象同时对该变量进行赋值时可能出现问题。

 

解决方法:在使用静态成员变量时使用 get set 方法。



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值