JAVA中的基础----pmd代码规范

本文结合实例,讲诉如何写出符合PMD编程规范的java代码。

阅读前需要有一个共识:优雅的代码一定是最让人喜欢的。

下面附上代码规范的pmd.xml文件的下载地址:https://github.com/jitongming/pmdForDev


目录

第一类:basic

第二类:unnecessary

第三类:braces

第四类:codesize

第五类:controversial

第六类:coupling

第七类:design

第八类:empty

第九类:finalizers

第十类:imports

第十一类:j2ee

第十二类:logging-java

第十三类:naming

第十四类:optimizations

第十五类:strictexception

第十六类:strings

第十七类:unusedcode


------------------------------我是可爱的分割线-----------------------------------

第一类:basic

1)ReturnFromFinallyBlock【不要在finally代码块中使用return】

  • Avoid returning from a finally block, this can discard exceptions.
  • 当在finally块中使用return时,编译器不会再对try、catch块中的非运行时异常进行检查,JVM不会再去捕获try块、catch块中的异常,程序的输出以finally块为准,即finally块的返回值或者finally块中抛出的异常。
public void test(){
    try{
        //......do something 
    }catch(Exception e){
        //......do something
    }finally{
        return "在这进行返回"; //避免在这里写return
    }
}

2)UnconditionalIfStatement【if语句判断条件,不能永远成立,必定是true或false】

  • Do not use "if" statements whose conditionals are always true or always false.
  • 当在if代码块执行前,会先检查判断条件是否成立,若条件必然成立,那没有必要用if语句。
public void test(){
    if(0<1){ //避免以绝对成立的条件作为判断依据
        //....do something
    }
}

 

第二类:unnecessary

1)UnnecessaryConversionTemporary【不要浪费一个object进行基础数值的字符串转换,使用包装类直接处理】

  • Avoid the use temporary objects when converting primitives to Strings. Use the static conversion methodson the wrapper classes instead.
  • 不要申请一个临时的对象去将“基本类型数值”转换为“字符串”,直接使用包装类处理。创建一个对象的开销是比较大的,尽量不要创建不必要的对象。
String a = new Integer(x).toString();//1.避免写法:浪费了一个object

String a= Integer.toString(x);//2.推荐写法

 

2)UnnecessaryFinalModifier【删除不必要的final修饰符】

  • When a class has the final modifier, all the methods are automatically final and do not need to betagged as such.
  • 如果class已经用final修饰过了,所有方法将自动默认为final型的,不需要再多此一举给方法加final修饰符。
public final class Test{

    public final String method1(){//1.避免写法
        return "test";
    }

    public String method2(){//推荐写法
        return "test";
    }
}

第三类:braces

1)ForLoopsMustUseBraces【for循环必须用{}包含起来】

  • Avoid using 'for' statements without using curly braces. If the code formatting or indentation is lost then it becomes difficult to separate the code being controlled from the rest.
  • for循环必须使用括号:避免在for循环时不使用{}。加上{}的好处:便于代码的理解和维护。
int a=0;
for(int i=0;i<100;i++) //1.避免写法
    a+=i;

for(int i=0;i<100;i++) {//2.推荐写法
    a+=i;
}

2)IfElseStmtsMustUseBraces【if..else..语句必须用{}包含起来】

  • Avoid using if..else statements without using surrounding braces. If the code formatting or indentation is lost then it becomes difficult to separate the code being controlled from the rest.
  • if…else…块必须使用括号:避免使用if…else…块时不使用{}。好处同上。
int a=1;
int b=2;

if(1==a) //1.避免写法
   b=a;     
else
   b+=a;


if(1==a){//2.推荐写法
   b=a;     
}else{
   b+=a;
}

3)IfStmtsMustUseBraces【if语句必须用{}包含起来】

  • Avoid using if statements without using braces to surround the code block. If the code formatting or indentation is lost then it becomes difficult to separate the code beingcontrolled from the rest.
  •  if块必须用括号:避免使用if块时不使用花括号{}。好处同上。
int a=1;
int b=2;

if(1==a) //1.避免写法
   b=a;     

if(1==a){//2.推荐写法
   b=a;     
}

4)WhileLoopsMustUseBraces【while循环必须用{}包含起来】

  • Avoid using 'while' statements without using braces to surround the code block. If the code formatting or indentation is lost then it becomes difficult to separate the code beingcontrolled from the rest.
  • while循环必须使用括号:避免使用while块时不使用{}。好处同上。
int a=1;
int b=10;

while(a

第四类:codesize

1)CyclomaticComplexity【圈复杂度不可过高】

  • Complexity directly affects maintenance costs is determined by the number of decision points in a method plus one for the method entry. The decision points include 'if', 'while', 'for', and 'case labels' calls. Generally, numbers ranging from 1-4 denote low complexity, 5-7 denote moderate complexity, 8-10 denotehigh complexity, and 11+ is very high complexity.
  • 决策点总数(圈复杂度)直接影响代码维护成本,决策点的标志有if、while和case。判断标准:1-4个决策点为低复杂度,5-7个决策点为中等复杂度,8-10个为高复杂度,11+个决策点为超高复杂度。

2)ExcessiveClassLength【class文件代码行不可过长】

  • Excessive class file lengths are usually indications that the class may be burdened with excessive responsibilities that could be provided by external classes or functions. In breaking these methodsapart the code becomes more managable and ripe for reuse.
  • 一个类文件的代码行数过长通常意味着这个类承担的职责过多或者代码重复过多,不符合单一职责和合成复用的设计原则,尽可能按职责进行拆分,并减少重复代码(复用性)。

第五类:controversial

1)UnnecessaryConstructor【删除不必要的构造器】

  • This rule detects when a constructor is not necessary; i.e., when there is only one constructor,its public, has an empty body, and takes no arguments.
  • 如果新增的构造器代码块为空并且无参数(默认构造器就是这样),那么这个构造器是没有必要的,删掉它。
publi class Test(){
    public Test(){//避免写法:如果新建一个构造器和默认构造器相同,删掉。
        //....do nothing
    }
        
}

第六类:coupling

1)LooseCoupling【松耦合】

  •  The use of implementation types as object references limits your ability to use alternateimplementations in the future as requirements change. Whenever available, referencing objects by their interface types provides much more flexibility.
  • 最好是通过接口的方式来实现对象的引用,增加灵活性。

第七类:design

1)ConstantsInInterface【不要在接口中放常量】

  • It's possible to place widely used constants in an interface. If a class implements such an interface, then the class can refer to those constants without a qualifying class name. This is only a minor advantage.Placing constants in an interface was a popular technique in the early days of Java, but now many consider it a distasteful use of interfaces, since interfaces should deal with the services provided by an object, not its data. As well, the constants used by a class are typically an implementation detail, but placing them in an interface promotes them to the public API of the class.
  • 避免接口包含常量:[1]接口仅仅是应该用来处理对象提供的service而不是data;[2]将常量放在接口中,意味着把这些常量当成了公共API。
//避免如下写法:
public interface Test{
    final static String A="a";
    
    final static String B="b";

    void testFirst(); 

}

public final class T implements Test{
    public void try(){
        arg =A;
    } 
    private String arg;//可能是null
}

2)AvoidInstanceofChecksInCatchClause【不要在catch代码块中检查异常类型】

  • Each caught exception type should be handled in its own catch clause.
  • 避免在catch块中使用instanceof:每个产生的异常类型都应该在自己的catch块中被处理。
1.避免写法
try{
    //......do something
}catch(Exception e){
    if(e instanceof IOException){  //不推荐在1个catch里处理多种exception
        //.....do something
    }
    if(e instanceof OutOfMemoryException){
        //.....do something
    }
}

2.推荐写法
try{  
    //....do something
}catch(IOException e1){
    //......do something  
}catch(OutOfMemoryException e2){
    //......do something
}

3)AvoidProtectedFieldInFinalClass【final修饰的类避免使用protected修饰】

  • Do not use protected fields in final classes since they cannot be subclassed.Clarify your intent by using private or package access modifiers instead.
  • 避免在final类中使用protected域:因为final类型的class不能被继承,所以不要使用protected域,通过使用private或包访问符来代替。
public final class Test{

    protected void method1(){//1.避免写法
        //.....dosomething
    }

    private void method1(){//2.推荐写法:可用private来代替protected
        //.....dosomething
    }
}

4)CloseResource【要释放使用完的资源】

  • Ensure that resources (like Connection, Statement, and ResultSet objects) are always closed after use.
  • 确保这些资源(譬如:Connection,Statement,和ResultSet对象)总在使用后被关闭。
public void test(){//使用资源完成后,要及时释放
    InputStream file = new FileInputStream(new File("/test/file.txt"));
    try{
        if(null!=file){
            file.read();//连接资源
        }
    }catch(IOException e){
        log.error("存在IO异常")//处理异常
    }finally{
        file.close();//释放资源        
    }
}

5)ConstructorCallsOverridableMethod【不要在构造器请求重写的方法】

  • Calling overridable methods during construction poses a risk of invoking methods on an incompletely constructed object and can be difficult to debug.It may leave the sub-class unable to construct its superclass or forced to replicate the construction process completely within itself, losing the ability to call super(). If the default constructor contains a call to an overridable method, the subclass may be completely uninstantiable. Note that this includes method calls throughout the control flow graph - i.e., if a constructor Foo() calls a private method bar() that calls a public method buz(), this denotes a problem.
  • 构造器调用了可重写的方法:在构造器中调用可被覆盖的方法可能引发在一个尚未构造完成的对象上调用方法的风险,而且是不易辨识的。它会使得子类不能构建父类或者自己强制重复构建过程,失去调用super()方法的能力。如果一个默认的构造器包含一个对可重写方法的调用,子类可能完全不能被实例化。注意这也包含在整个控制流图上的方法调用——例如:如果构造器Foo()调用了私有方法bar(),而bar()又调用了公开的方法buz(),这就会导致问题。
public class Test(){

    public Test(){
        getString();//避免写法:可能导致空指针NullException
    }
    
    private String getString(){
        return getMyWord();
    }

    public String getMyWord(){
        return "A is best";
    }
}

6)DefaultLabelNotLastInSwitchStmt【switch语句中default代码片段要放在最后】

  • By convention, the default label should be the last label in a switch statement.
  • switch表达式中default块应该在最后:按照惯例,default标签应该是switch表达式的最后一个标签。

7)FinalFieldCouldBeStatic【final类型的域用static修饰】

  • If a final field is assigned to a compile-time constant, it could be made static, thus saving overhead in each object at runtime.
  • 如果一个final类型的域在编译时被赋值为常量,它也可以是static的,那样就在每个对象运行时节省开支。
public class Test{

    private final a="A";//1.避免写法
    
    private final static a="A";//2.推荐写法
}

8)ImmutableField【不可变的域】

  • Identifies private fields whose values never change once they are initialized either in the declaration of the field or by a constructor. This helps in converting existing classes to becoming immutable ones.
  • 识别出一旦被声明就赋值或通过构造器赋值后就不再改变的私有域,可以加final修饰。

9)InstantiationToGetClass【不要用getClass()去实例化对象】

  • Avoid instantiating an object just to call getClass() on it; use the .class public member instead.
  • 避免通过访问getClass()实例化对象,使用.class这个公共属性代替。
1.避免写法
Class c = new Integer().getClass();
2.推荐写法
Class c = Integer.class;

10)MissingBreakInSwitch【switch语句必须使用break语句】

  •  Switch statements without break or return statements for each case optionmay indicate problematic behaviour. Empty cases are ignored as these indicate an intentional fall-through.
  • switch表达式缺少内含的break块可能是bug。
public void test(int status){
    switch(status){
        case CAT:
           eatCatFood(); 
           //......避免在执行完成后,不进行break
        case DOG:
           eatDogFood();
           //......避免在执行完成后, 不进行break
        case FISH:
           eatFishFood();
           break;//推荐在执行完后,进行break
        default:
           eatPigFood();
           break;
    }
}

11)PositionLiteralsFirstInComparisons【进行参数比较时,文字放在前面】

  • Position literals first in comparisons, if the second argument is null then NullPointerExceptions can be avoided, they will just return false.
  • 把字面量放在比较式的前面:在字符串比较时,将字面量放在前面-这种方法能够避免当字符串为空时的空指针异常,只是返回false。
public void test(String a){
    if(a.equals("luck")){//1.避免写法:这样写,当a为null的时候,会产生空指针异常。
        //......do something
    }
    
    if("luck".equals(a)){//2.推荐写法
        //......do something
    }
}

12)SimplifyBooleanExpressions【简化boolean表达式】

  • Avoid unnecessary comparisons in boolean expressions, they serve no purpose and impacts readability.
  • 避免布尔表达式之间无用的比较——只会使代码复杂化。
public boolean test(){//1.避免写法:a==true这个比较没有必要
    boolean a=true;
    return a==true?true:false;   
}

public boolean test(int a,int b){//2.推荐写法
    boolean a=true;
    return a;  
}

13)SimplifyBooleanReturns【简化boolean返回方式】

  • Avoid unnecessary if-then-else statements when returning a boolean. The result ofthe conditional test can be returned instead.
  • 避免在返回布尔量时写不必要的if..then..else表达式。
public boolean test(int a,int b){//1.避免写法
    if(a>b){
        return true;
    }
    return false;
}

public boolean test(int a,int b){//2.推荐写法:简化后逻辑更清晰
    return a>b;
}

14)SwitchStmtsShouldHaveDefault【switch语句必须包含default语句】

  •  All switch statements should include a default option to catch any unspecified values.
  • Switch表达式应该有default块,可能存在case中没有预料到的情况,在default中处理。
public void test(int a){
    switch(a){
        case ARG1:
            //......do something
            break;
        case ARG2:
            //......do something
            break;
        case ARG3:
            //......do something
            break;
        default:            //推荐写法:switch语句最后把default给加上
            //......do something
            break;
    }

}

第八类:empty

1)EmptyCatchBlock【catch代码块不要为空】

  • Empty Catch Block finds instances where an exception is caught, but nothing is done. In most circumstances, this swallows an exception which should either be acted on or reported.
  • catch代码块中抓到异常后,需要做一些处理,比如打印日志。不要什么都不处理,这样无法感知到这种异常,catch将失去意义。
public void test(){
    try{
         FileInputStream fis = new FileInputStream("/test/file.txt");
    }catch(IOException e){
        //do nothing 避免在catch模块什么都不做,捕获的异常需要被感知。
    }
}

2)EmptyFinallyBlock【finally代码块不要为空】

  • Empty finally blocks serve no purpose and should be removed.
  • finally代码如果不做任何事情,请把它删除,因为finally必然执行,如果什么都不做,finally就没有存在的必要。
public void test(){
    try{
         FileInputStream fis = new FileInputStream("/test/file.txt");
    }catch(IOException e){
        log.error("存在IO异常");
    }finally{
        //do nothing 避免finally为空:如果什么都不做,请删除finally代码块
    }
}

3)EmptyIfStmt【if代码块不要为空】

  • Empty If Statement finds instances where a condition is checked but nothing is done about it.
  • if的判断条件成立后,如果不做处理,那这个if代码块将没有意义,需要加入必要的处理逻辑。若不做处理,删除不必要的if判断。
public void  test(int a){
    if(a>1){
        //do nothing 避免if条件成立后,不做任何不处理。要么做处理,要么删除这个if
    }
}

4)EmptySwitchStatements【删掉空的switch语句】

  • Empty switch statements serve no purpose and should be removed.
  • switch代码不要为空,如果switch后不做处理,就删除不必要的switch代码。

5)EmptySynchronizedBlock【删掉空的同步语句】

  • Empty synchronized blocks serve no purpose and should be removed.
  • 如果synchronized 代码块内部是空,把它删除。

6)EmptyTryBlock【删掉空的try语句】

  • Avoid empty try blocks - what's the point?
  • 如果try代码块内部为空,把它删除。

7)EmptyWhileStmt【删掉空的while语句】

  • Empty While Statement finds all instances where a while statement does nothing. If it is a timing loop, then you should use Thread.sleep() for it; if it isa while loop that does a lot in the exit expression, rewrite it to make it clearer.
  • 如果while代码块内部为空,把它删除。

第九类:finalizers

1)AvoidCallingFinalize【不要请求finalize】

  • The method Object.finalize() is called by the garbage collector on an object when garbage collection determinesthat there are no more references to the object. It should not be invoked by application logic.
  • JVM的事让它自己做,在一个对象不再被引用时,垃圾回收机制自动对这个对象进行object.finalize().在代码中不要再调用它。

2)FinalizeDoesNotCallSuperFinalize【finalize不要请求super.finalize()】

  • If the finalize() is implemented, its last action should be to call super.finalize.
  • 如果实现了finalize(),那么最后一个执行操作应该时super.finalize()。

3)FinalizeShouldBeProtected【finalize需要protected修饰】

  • When overriding the finalize(), the new method should be set as protected. If made public, other classes may invoke it at inappropriate times.
  • 当重写finalize()方法时,新方法需要用protected进行修饰。因为一旦public,不能保证其他类会不会调用它,造成错误或异常。

第十类:imports

1)DontImportJavaLang【不要对java.lang包进行import】

  • Avoid importing anything from the package 'java.lang'. These classes are automatically imported (JLS 7.5.3).
  • 避免import任何前缀为java.lang的资源,因为这个资源是被默认import的。
import java.lang.Integer;//避免写法:java.lang.*已经被默认import,不要在引入。
import java.lang.Long;//避免写法

2)DuplicateImports【不要重复import相同的资源】

  • Duplicate or overlapping import statements should be avoided.
  • 避免重复import相同的资源。
import java.util.*;

//避免:上面一行代码已经把util全部引用了,没必要重复的引用内部类
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

3)ImportFromSamePackage【不要重复引用同一个包】

  • There is no need to import a type that lives in the same package.
  • 如果已有的外部包中已经有了需要的方法,没有必要重复引用。
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Collections;//避免写法:第一行已经import同样的内容,不要重复。

4)UnusedImports【不要import未使用的资源】

  • Avoid the use of unused import statements to prevent unwanted dependencies.
  • 为了不形成不必要的依赖,如果被import的资源未被使用,删掉它。

第十一类:j2ee

1)DoNotCallSystemExit【不要请求system.exit()】

  • Web applications should not call System.exit(), since only the web container or the application server should stop the JVM. This rule also checks for the equivalent call Runtime.getRuntime().exit().
  • web应用不应该请求system.exit(),只有web容器或者应用服务可以停止JVM。同样也不要出现Runtime.getRuntime().exit()
public void test(){
    System.exit(0);//避免1:运行应用的时,不要调用退出。

    Runtime.getRuntime().exit();//避免2:不要停止JVM,这时container做的事,不要多管闲事。
}

第十二类:logging-java

1)AvoidPrintStackTrace【不要使用printStackTrace()】

  • Avoid printStackTrace(); use a logger call instead.
  • 捕获catch到异常,建议不要用printStackTrace()方法,建议用日志log打印出来。原因是printStackTrace打印出来的堆栈日志是混在一起的,而log打印的日志是逐行的。根本原因是printStackTrace默认使用了System.err输出流进行输出,与System.out是两个不同的输出流,那么在打印时自然就形成了交叉,再就是输出流是有缓冲区的,所以对于什么时候具体输出也形成了随机。
public void test(){
    try{
        //.....do something
    }catch(IOException e){

        e.printStackTrace();//1.避免写法

        log.error(e.getMessage);//2.推荐写法
    }
}

2)MoreThanOneLogger【一个类只要一个日志对象】

  • Normally only one logger is used in each class.
  • 正常的代码都是在一个类只有一个logger对象
public class Test{
    private static final Logger log = LoggerFactory.getLogger(Test.class);
    //避免:正常代码,不会有下面log2
    private static final Logger log2 = LoggerFactory.getLogger(Test.class);
}

3)SystemPrintln【不要使用System.println()】

  • References to System.(out|err).print are usually intended for debugging purposes and can remain inthe codebase even in production code. By using a logger one can enable/disable this behaviour atwill (and by priority) and avoid clogging the Standard out log.
  • 通常在调试的时候,使用System.out.println()或者System.err.println(),代码中过多时,容易阻塞标准输出的日志,并且无法灵活控制。实际生产中,建议使用logger,通过优先级控制(禁用/启用)日志的输出行为。
public void test(int a,int b){
      if(a>b){

          System.out.println("a>b");//1.避免写法

          log.info("a>b");//2.推荐写法
      }
}

第十三类:naming

1)AvoidDollarSigns【不要用dollar符号】

  • Avoid using dollar signs in variable/method/class/interface names.
  • 避免在变量、方法、类和接口的命名中使用dollor符号。

2)ClassNamingConventions【约定:类名要用大驼峰命名】

  • Class names should always begin with an upper case character.
  • 类的命名通常约定使用大驼峰形式,即第一个字符要大写。

3)MethodWithSameNameAsEnclosingClass【方法命名不要和类型相同】

  • Non-constructor methods should not have the same name as the enclosing class.
  • 不是构造器的方法不要和类名一样,这样更容易造成代码出错,使程序混乱和不易理解。
public class Test{
    public Test(){
        //这是一个构造器,是构造器的必要写法
    }
    public void Test(){//避免:方法名请尽量不要和类名相同
        //....do something这是一个方法
    }
}

第十四类:optimizations

1)LocalVariableCouldBeFinal【只赋值一次的局部变量用final修饰】

  • A local variable assigned only once can be declared final.
  • 局部变量只被赋值一次,就声明为final。

2)MethodArgumentCouldBeFinal【未重新赋值的方法参数用final修饰】

  • A method argument that is never re-assigned within the method can be declared final.
  • 一个方法参数如果没被重新赋值,就声明为final。

第十五类:strictexception

1)AvoidCatchingThrowable【不要捕获Throwable】

  • Catching Throwable errors is not recommended since its scope is very broad. It includes runtime issues such as OutOfMemoryError that should be exposed and managed separately.
  • 不推荐捕获throwable错误,因为这种错误范围太大,并且涉及到运行时异常(如内存溢出)需要及时暴露,便于恰当处理。
public void test(){
    try{
        //.............do something    
    }catch(Throwable t){//避免捕获throwabale
        log.error(t.getMessage());
    }
}

2)AvoidThrowingNullPointerException【不要抛空指针异常】

  • Avoid throwing NullPointerExceptions. These are confusing because most people will assume that thevirtual machine threw it. Consider using an IllegalArgumentException instead; this will beclearly seen as a programmer-initiated exception.
  • 不要抛”空指针异常“,代码中用“非法异常”代替“空指针异常”,能使开发者意识到是程序出问题了。

3)AvoidThrowingRawExceptionTypes【不要抛原始异常】

  • Avoid throwing certain exception types. Rather than throw a raw RuntimeException, Throwable,Exception, or Error, use a subclassed exception or error instead.
  • 不要抛原始异常和错误,如RuntimeException, Throwable,Exception或 Error,建议抛更加具体的异常或错误,即抛原始异常的子类。

4)DoNotExtendJavaLangError【不要继承java.lang.error】

  • Errors are system exceptions. Do not extend them.
  • Error都是系统级别的异常,不要对error进行继承。

5)DoNotThrowExceptionInFinally【不要在finally代码块抛异常】

  • Throwing exceptions within a 'finally' block is confusing since they may mask other exceptions or code defects.Note: This is a PMD implementation of the Lint4j rule "A throw in a finally block".
  • 在finally代码块中抛异常可能会覆盖其他的异常或代码缺陷,使我们无法发现潜在的错误。
public void test(){
    try{
        //...............do something
    }catch(Exception e){
        //................log.error(e.getMessage())捕获异常
    }finally{
        throw new Exception(); //避免这样处理
    }
}

6)ExceptionAsFlowControl【不要用异常作为代码逻辑控制元】

  • Using Exceptions as form of flow control is not recommended as they obscure true exceptions when debugging.Either add the necessary validation or use an alternate control structure.
  • 不推荐使用异常作为代码逻辑控制元,因为这样做的话,真正的异常可能被掩盖。替代方案是:增加必要校验或者必要的控制逻辑。

7)SignatureDeclareThrowsException【具有声明抛出的异常】

  • It is unclear which exceptions that can be thrown from the methods.It might be difficult to document and understand the vague interfaces.Use either a class derived from RuntimeException or a checked exception.JUnit classes are excluded.
  • 不确定方法中能够抛出什么样的具体异常。为模糊的接口提供证明并理解它是很困难的。抛出的异常类要么从RuntimeException中继承或者抛出一个被检查的异常。另外,这个不适用对JUnit单元测试类的处理。

第十六类:strings

1)StringInstantiation【不要实例化String对象】

  • Avoid instantiating String objects; this is usually unnecessary since they are immutable and can be safely shared.
  • 避免对字符串String对象进行实例化,不要多次一举,字符串一般时不可变的,可安全共享的。
//1.避免写法:这种方式会在堆中,先创建一个a对象,值为“我是一个字符串”。
//如果string池中不包含“我是一个字符串”,则会在string池中再创建一个“我是一个字符串”对象。
//如果string池中包含“我是一个字符串”,则会指向这个对象地址。
String a=new String("我是一个字符串");

//2.推荐写法:这种方法会检查string池中是否包含“我是一个字符串”对象。
//如果有的话,a直接指向改对象内存地址,
//如果没有的话,会在string池新建新建该对象,a在指向这个新建对象的内存地址。
String a="我是一个字符串";

第十七类:unusedcode

1)UnusedFormalParameter【删除未被使用的参数】

  • Avoid passing parameters to methods or constructors without actually referencing them in the method body.
  • 避免将实际未被使用或进行逻辑处理的参数传到方法或构造器中,删除掉。

2)UnusedLocalVariable【删除未被使用的局部变量】

  • Detects when a local variable is declared and/or assigned, but not used.
  • 检查声明的局部变量是否被使用,如果未使用,删除掉。

3)UnusedPrivateField【删除未被使用的私有域】

  • Detects when a private field is declared and/or assigned a value, but not used.
  • 检查声明的私有域是否被使用,如果未使用,删除掉。

4)UnusedPrivateMethod【删除未使用的private方法】

  •  Unused Private Method detects when a private method is declared but is unused.
  • 检查声明的私有方法是否被使用,如果未使用,删除掉。

你可能感兴趣的:(java,编程基础)