Full Stack Web Developer.
Syaku (샤쿠)

Java, JS (ES6+), Spring, Spring security, jQuery, Reactjs, Bootstrap.

        

07-12 08:23


Spring Boot 2 보기 Front-end 보기 DevOps 보기 Spring 3 보기 Spring Security 3 보기

PMD - 코드 분석 도구 룰셋에 대한 설명 : Java Code Inspection , Rule set

PMD - 코드 분석 도구 룰셋에 대한 설명 : Code Inspection , Rule set


설명이 주관적이라 상황에 따라 올바르지 않을 수 있습니다. 

Java 1.7.x
PMD 5.0.4
IntelliJ IDEA - QAPlug

PMD 메뉴얼 : https://pmd.github.io/pmd-5.5.1
PMD 한글 메뉴얼 : http://isfasiel.tistory.com/category/PMD
네이버 번역기 : http://labspace.naver.com/nmt/
구글 번역기 : https://translate.google.co.kr/

AvoidCatchingGenericException

#maintainability #strict-exceptions

rulesets/java/strictexception.xml/AvoidCatchingGenericException

NullPointerException, RuntimeException, Exception 을 try-catch 절에서 잡지말라. 더 분명한 예외를 사용하라.

Avoid catching generic exceptions such as NullPointerException, RuntimeException, Exception in try-catch block

NullPointerException, RuntimeException, Exception과 같은 일반적인 예외 사항을 catch하지 마십시오.

public class PrimitiveType {
    
  public void downCastPrimitiveType() {
    try {
      System.out.println(" i [" + i + "]");
    } catch(Exception e) {
      e.printStackTrace();
    } catch(RuntimeException e) {
      e.printStackTrace();
    } catch(NullPointerException e) {
      e.printStackTrace();
    }
  } 
}

AvoidConstantsInterface

#maintainability #design

rulesets/java/design.xml/AvoidConstantsInterface

상수만 있는 인터페이스를 만들지 마라.

An interface should be used only to characterize the external behaviour of an implementing class: using an interface as a container of constants is a poor usage pattern and not recommended.

인터페이스는 구현하는 클래스의 외부 동작을 특성화하는 데에만 사용되어야 합니다. 상수의 컨테이너로 인터페이스를 사용하는 것은 사용하지 않는 것이 좋지 않고 권장되지 않는다.

// 이런 인터페이스는 만들지 않는 다.
public interface ConstantsInterface {
   public static final int CONSTANT1=0;
   public static final String CONSTANT2="1";
}

AvoidThrowingRawExceptionTypes

#maintainability #strict-exceptions

rulesets/java/strictexception.xml/AvoidThrowingRawExceptionTypes

RuntimeException, Throwable, Exception 또는 오류를 전달하지 말고 서브클래스 예외를 사용하라.

Avoid throwing certain exception types. Rather than throw a raw RuntimeException, Throwable, Exception, or Error, use a subclassed exception or error instead.

특정 예외 유형을 throw 하지 마십시오. RuntimeException, Exception, Exception 또는 Error를 throw 하는 대신 서브클래스 예외를 throw 하거나 오류를 대신 throw 합니다.

public class Foo {
    public void bar() throws Exception {
        throw new Exception(); // 나쁨
    }
    
    public void bar() {
        try {
            throw new CustomException(); // 좋음
        } catch(CustomException e) {
        
        }
    }
}

CallSuperInConstructor : 보류중

#maintainability #controversial

rulesets/java/controversial.xml/CallSuperInConstructor

사용할 이유를 정확히 알 수 없어 분석이 필요하며, 룰 사용여부는 추후 판단한다.

자식클래스에 생성자(constructor)가 있으면 수퍼클래스를 호출하는 것이 좋다.

It is a good practice to call super() in a constructor. If super() is not called but another constructor (such as an overloaded constructor) is called, this rule will not report it.

public class Foo extends Bar{
  public Foo() {
   // Bar 생성자를 호출
   super();
  }
 public Foo(int code) {
  // do something with code
   this();
   // no problem with this
  }
}

CollapsibleIfStatements

#maintainability #basic

rulesets/java/basic.xml/CollapsibleIfStatements

불필요한 if문의 깊이를 간소화ㄴ 하라.

Sometimes two consecutive ‘if’ statements can be consolidated by separating their conditions with a boolean short-circuit operator.

void bar() {
    if (x) {            // 나쁨
        if (y) {
        }
    }
}

void bar() {
    if (x && y) {       // 좋음
    }
}

ExcessiveImports

#maintainability #coupling

rulesets/java/coupling.xml/ExcessiveImports

클래스에 import 수가 minimum 설정보다 많으면 결합도가 높다고 판단하여 위반으로 판단한다. 

A high number of imports can indicate a high degree of coupling within an object. This rule counts the number of unique imports and reports a violation if the count is above the user-specified threshold.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/coupling/ExcessiveImportsRule.html

- properties

NameDefaultDescription
minimum30.0Minimum reporting threshold

EmptyCatchBlock

#maintainability #empty-code

rulesets/java/empty.xml/EmptyCatchBlock

try-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.

public void doSomething() {
  try {
    FileInputStream fis = new FileInputStream("/tmp/bugger");
  } catch (IOException ioe) {
      // 나쁨
  }
}

- properties

NameDefaultDescription
allowCommentedBlocksfalseEmpty blocks containing comments will be skipped

GuardDebugLogging

#maintainability #logging-jakarta-commons

rulesets/java/logging-jakarta-commons.xml/GuardDebugLogging

로그 디버그를 남길때 문자열을 concat(+) 연결할때 isDebugEnabled 사용해라.

When log messages are composed by concatenating strings, the whole section should be guarded by a isDebugEnabled() check to avoid performance and memory issues.

log 문자열이 concatenating 문자열로 구성되어 있는 경우, 전체 섹션은 성능 및 메모리 문제를 방지하기 위해 isDebugEnabled()체크 표시를 해야 합니다.

__log.debug("log something"); // 좋음
__log.debug("log something with exception", e); // 좋음
__log.debug("log something" + " and " + "concat strings"); // 나쁨
__log.debug("log something" + " and " + "concat strings", e); // 나쁨

if (__log.isDebugEnabled()) { // 괜찮음
    __log.debug("bla" + "",e );
}

ImmutableField

#maintainability #design

rulesets/java/design.xml/ImmutableField

private 인스턴스변수가 직접 초기화 및 생성자에 의한 초기화 후 변경되지 않는 다면 final 키워드를 추가한다.

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.

public class Foo {
  private int x; // final 필요
  public Foo() {
      x = 7; // 생성자에 의한 초기화
  }
  
  public void foo() {
     int a = x + 2;
  }
}

or

class Foo {

    private String name; // final 필요
    
    public Foo(String name) {
        this.name = name;
    }

}

ImportFromSamePackage

#maintainability #import-statements

rulesets/java/imports.xml/ImportFromSamePackage

동일한 패키지 영역에서는 Import를 하지 않아도 된다.

There is no need to import a type that lives in the same package.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/imports/ImportFromSamePackageRule.html

package foo;
 
import foo.Buz; // 필요하지 않음
import foo.*; // 필요하지 않음
 
public class Bar{}

LooseCoupling

#maintainability #coupling

rulesets/java/coupling.xml/LooseCoupling

구현 클래스 타입을 참조하지 말고 인터페이스 타입을 참조하라.

The use of implementation types as object references limits your ability to use alternate implementations in the future as requirements change. Whenever available, referencing objects by their interface types provides much more flexibility.

구현 유형을 개체 참조 형식으로 사용하는 것은 향후 변경 사항이 변경될 때마다 대체 구현을 제한할 수 있습니다. 인터페이스 유형별로, 인터페이스 유형별로 개체를 참조하면 훨씬 더 많은 유연성을 제공할 수 있습니다.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/coupling/LooseCouplingRule.html

Map<String, ModuleValue> map = new LinkedHashMap<String, String>(); // 좋음

LinkedHashMap <String, ModuleValue> map = new LinkedHashMap<String, String>(); // 나쁨

NullAssignment

#maintainability #controversial

rulesets/java/controversial.xml/NullAssignment

변수를 초기화한 후 null 을 다시 대입하지마라. 또한 try-catch 절에서 객채를 선언하지마라.

Assigning a “null” to a variable (outside of its declaration) is usually bad form. Sometimes, this type of assignment is an indication that the programmer doesn’t completely understand what is going on in the code.

NOTE: This sort of assignment may used in some cases to dereference objects and encourage garbage collection.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/controversial/NullAssignmentRule.html

public void bar() {
  Object x = null; // 괜찮음
  x = new Object();
  
  ... 생략 ...

  x = null; // 나쁨
  
  또한
  
  Object obejct; // 1
  
  try {
  
    object = new Object(); // 1 = 괜찮음
    Object object = new Object(); // 2 = 나쁨
  
  } catch(e) {
  
  }
  
}

PreserveStackTrace

#maintainability #design

rulesets/java/design.xml/PreserveStackTrace

catch절에서 새로운 예외로 던질때 인자로 원래 예외를 전달하지 않으면 디버깅이 어려워 진다.

Throwing a new exception from a catch block without passing the original exception into the new exception will cause the original stack trace to be lost making it difficult to debug effectively.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/design/PreserveStackTraceRule.html

public class Foo {
    void good() {
        try{
            Integer.parseInt("a");
        } catch (Exception e) {
            throw new Exception(e); // first possibility to create exception chain
        }
        try {
            Integer.parseInt("a");
        } catch (Exception e) {
            throw (IllegalStateException)new IllegalStateException().initCause(e); // second possibility to create exception chain.
        }
    }
    
    void bad() {
        try{
            Integer.parseInt("a");
        } catch (Exception e) {
            throw new Exception(e.getMessage()); // 나쁨
        }
    }
}

SimplifyBooleanExpressions

#maintainability #design

rulesets/java/design.xml/SimplifyBooleanExpressions

boolean 을 비교할때 불필요한 연산을 간결하게 한다.

Avoid unnecessary comparisons in boolean expressions, they serve no purpose and impacts readability.


if (is == false) // 간결하게?
if (!is) // 간결하다.

public class Bar {
  // can be simplified to
  // bar = isFoo();
  private boolean bar = (isFoo() == true);

  public isFoo() { return false;}
}

SingularField

#maintainability #design

rulesets/java/design.xml/SingularField

불필요한 인스턴스 변수는 피하고 지역변수로 사용하라.

Fields whose scopes are limited to just single methods do not rely on the containing object to provide them to other methods. They may be better implemented as local variables within those methods.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/design/SingularFieldRule.html

public class Foo {
    private int x;  // 필요없는 인스턴스변수
    public void foo(int y) {
     x = y + 5;
     return x;
    }
    
    public void foo(int y) {
     int x = y + 5; // 좋음
    }
}

- properties

NameDefaultDescription
disallowNotAssignmentfalseDisallow violations where the first usage is not an assignment
checkInnerClassesfalseCheck inner classes

UnnecessaryReturn

#maintainability #unnecessary

rulesets/java/unnecessary.xml/UnnecessaryReturn

불필요한 return 은 사용하지마라.

Avoid the use of unnecessary return statements.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/unnecessary/UnnecessaryReturnRule.html

public class Foo {
  public void bar() {
    int x = 42;
    return; // 필요없음
  }
}

UnusedLocalVariable

#maintainability #unused-code

rulesets/java/unusedcode.xml/UnusedLocalVariable

사용하지 않는 지역변수가 존재한다. 제거하거나 주석처리 한다.

Detects when a local variable is declared and/or assigned, but not used.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/unusedcode/UnusedLocalVariableRule.html

public class Foo {
    public void doSomething() {
        int i = 5; // 사용안함
    }
}

UnusedPrivateField

#maintainability #unused-code

rulesets/java/unusedcode.xml/UnusedPrivateField

사용하지 않는 멤버변수가 존재한다. 제거하거나 주석처리 한다.

Detects when a private field is declared and/or assigned a value, but not used.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/unusedcode/UnusedPrivateFieldRule.html

public class Something {
  private static int FOO = 2; // 사용안함
  private int i = 5; // 사용안함
  private int j = 6;
  public int addOne() {
    return j++;
  }
}

UnusedPrivateMethod

#maintainability #unused-code

rulesets/java/unusedcode.xml/UnusedPrivateMethod

사용하지 않는 private 메서드가 존재한다. 제거하거나 주석처리한다.

Unused Private Method detects when a private method is declared but is unused.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/unusedcode/UnusedPrivateMethodRule.html

public class Something {
    private void foo() {} // 사용안함
}

UseCollectionIsEmpty

#maintainability #design

rulesets/java/design.xml/UseCollectionIsEmpty

빈 Collection 을 검사할때 isEmpty 를 사용하라.

The isEmpty() method on java.util.Collection is provided to determine if a collection has any elements. Comparing the value of size() to 0 does not convey intent as well as the isEmpty() method.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/design/UseCollectionIsEmptyRule.html

public class Foo {

    if (list.size() > 0) // 나쁨
    if (!list.isEmpty()) // 좋음
    
    or

    void good() {
        List foo = getList();
        if (foo.isEmpty()) {
            // blah
        }
    }

    void bad() {
        List foo = getList();
            if (foo.size() == 0) {
                // blah
            }
        }
}

UselessParentheses

#maintainability #unnecessary

rulesets/java/design.xml/UseCollectionIsEmpty

쓸모없는 괄호를 제거하라.

Useless parentheses should be removed.

연산자 우선순위설명
. [] ()필드 액세스, 배열변수 인덱스, 기능함수 호출, 식 묶기
++ -- - ~ ! delete new typeof void단항 연산자, 데이터 형식 반환, 개체 만들기, undefined 값
* / %곱하기, 나누기, 나머지 나누기
+ -더하기, 빼기, 문자열 연결
<< >> >>>비트 이동
< <= > >= instanceof보다 작음, 작거나 같음, 보다 큼, 크거나 같음, instanceof
== != === !==같음, 같지 않음, 동치, 동치가 아님
&비트 논리곱
^비트 배타적 논리합
|비트 논리합
&&논리곱
||논리합
?... :...조건부 삼항식
= opr= <<=할당, 복합 할당, 연산자 할당, 비트 할당
,컴마로 분리된 여러 식 계산

AvoidCatchingNPE

#reliability #strict-exception

rulesets/java/strictexception.xml/AvoidCatchingNPE

정상적인 코드에 NullPointerExceptions 으로 catch 하지마라.

Code should never throw NullPointerExceptions under normal circumstances. A catch block may hide the original error, causing other, more subtle problems later on.

코드는 정상적인 상황에서는 절대로 무시되어서는 안 된다. catch블록은 원래의 오류를 숨길 수 있으며, 나중에 더 미묘한 문제를 야기할 수 있습니다.

public class Foo {
  void bar() {
    try {
      
      }  catch (NullPointerException npe) { // 나쁨
    }
  }
}

ConstructorCallsOverridableMethod : 자세한 정리필요 (보류중)

#reliability #design

rulesets/java/design.xml/ConstructorCallsOverridableMethod

상속하여 오버라이딩되면 부모의 메서드는 사용할 수 없게 된다 그래서 부모 클래스 생성자에서 부모 메서드(오버라이딩된 메서드)를 호출할 경우 NullPointerExceptions이 발생된다.

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.

public class SeniorClass {
  public SeniorClass(){
      toString(); //may throw NullPointerException if overridden
  }
  public String toString(){
    return "IAmSeniorClass";
  }
}
public class JuniorClass extends SeniorClass {
  private String name;
  public JuniorClass(){
    super(); //Automatic call leads to NullPointerException
    name = "JuniorClass";
  }
  public String toString(){
    return name.toUpperCase();
  }
}

// 해결하기
public final class SeniorClass { // final 상속을 금지시키기

or

// 생성자에서 메서드를 호출하지 않기.
public SeniorClass(){
}

PositionLiteralsFirstInComparisons

#reliability #design

rulesets/java/design.xml/PositionLiteralsFirstInComparisons

if문에서 NullPointerExceptions을 피하기 위해 리터널 값을 비교 대상자로 사용하라.

Position literals first in comparisons, if the second argument is null then NullPointerExceptions can be avoided, they will just return false.

class Foo {
  boolean bar(String x) {
    return x.equals("2"); // NullPointerExceptions 발생 가능성 있음
    
    return "2".equals(x); // 좋음
  }
}

ArrayIsStoredDirectly

#reliability #security-code-guidelines

rulesets/java/sunsecure.xml/ArrayIsStoredDirectly

매개변수 배열형은 call by reference 이므로 값이 변할 수 있다. 그래서 안정성을 보장하기 위해 복사해서 사용한다.

Constructors and methods receiving arrays should clone objects and store the copy. This prevents future changes from the user from affecting the original array.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/sunsecure/ArrayIsStoredDirectlyRule.html

public class Foo {
  private String [] x;
    public void foo (String [] param) {
      // Don't do this, make a copy of the array at least
      this.x=param;
    }
}

public void setValues(String[] newVals) {
     this.vals = ( newVals == null ? null : newVals.clone() );
}

or

public void setValues(String[] newVals) {
     this.vals = ( newVals == null ? null : Arrays.copyOf(newVals, newVals.length) );
}

MethodReturnsInternalArray

#reliability #security-code-guidelines

rulesets/java/sunsecure.xml/MethodReturnsInternalArray

배열형은 call by reference 이므로 값이 변할 수 있다. 그래서 안정성을 보장하기 위해 복사해서 사용한다.

Exposing internal arrays to the caller violates object encapsulation since elements can be removed or replaced outside of the object that owns it. It is safer to return a copy of the array.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/sunsecure/MethodReturnsInternalArrayRule.html

public class SecureSystem {
  UserData [] ud;
  public UserData [] getUserData() {
      // 복사해서 반환한다. System.arraycopy or clone
      return ud;
  }
}

SimpleDateFormatNeedsLocale

#reliability #design

rulesets/java/design.xml/SimpleDateFormatNeedsLocale

SimpleDateFormat 인스턴스를 생성할 때 Locale를 지정해야 한다.

Be sure to specify a Locale when creating SimpleDateFormat instances to ensure that locale-appropriate formatting is used.

public class Foo {
  // Locale.
  private SimpleDateFormat sdf = new SimpleDateFormat("pattern");
  
  private SimpleDateFormat sdf = new SimpleDateFormat("pattern", );
}

UnsynchronizedStaticDateFormatter

#reliability #design

rulesets/java/design.xml/UnsynchronizedStaticDateFormatter

SimpleDateFormat 클래스는 동기화를 지원하지 않기때문에 직접 동기화를 적용해야 한다.

SimpleDateFormat instances are not synchronized. Sun recommends using separate format instances for each thread. If multiple threads must access a static formatter, the formatter must be synchronized either on method or block level.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/design/UnsynchronizedStaticDateFormatterRule.html

public class Foo {
    private static final SimpleDateFormat sdf = new SimpleDateFormat();
    void bar() {
        sdf.format(); // 비동기화
    }
    synchronized void foo() {
        sdf.format(); // 좋음
    }
}

or

public class Foo {
    void bar() {
        // Apache Commons-lang 라이브러리 사용.
        FastDateFormat sdf = new FastDateFormat();
        sdf.format();
    }
}

UnusedImports

#reliability #import-statements

rulesets/java/imports.xml/UnusedImports

사용하지 않는 import를 제거하라.

Avoid the use of unused import statements to prevent unwanted dependencies.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/imports/UnusedImportsRule.html

import java.io.File; // 필요없음
public class Foo {}

UseLocaleWithCaseConversions

#reliability #design

rulesets/java/design.xml/UseLocaleWithCaseConversions

대소문자 치환할때 Locale 사용한다. 그래서 정확한 비교가 가능해진다.

When doing String.toLowerCase()/toUpperCase() conversions, use Locales to avoids problems with languages that have unusual conventions, i.e. Turkish.


// 터키어의 문자비교
class Foo {
 // 터키어의 문자를 영어와 비교할 수 없다.
 if (x.toLowerCase().equals("list")) { }
 
 // 아래와 같이 터키어를 영어로 변경 후 비교할 수 있다.
 // This will not match "LIST" when in Turkish locale
 // The above could be
 if (x.toLowerCase(Locale.US).equals("list")) { }
 
 
 // 좋음
 String z = a.toLowerCase(Locale.EN);
 
 // 일반적인 영어 인 경우
 String z = a.toLowerCase(Locale.getDefault());
}

ShortVariable

#usability #naming

rulesets/java/naming.xml/ShortVariable

멤버변수, 지역변수, 매개변수 등 변수 이름의 길이를 minimum 설정보다 짧게 하지마라.

Fields, local variables, or parameter names that are very short are not helpful to the reader.

public class Something {
    private int q = 15;                         // q 나쁨
    public static void main( String as[] ) {    // as 나쁨
        int r = 20 + q;                         // r 나쁨
        for (int i = 0; i < 10; i++) {          // 반복문의 변수는 검사 대상에서 제외된다.
            r += q;
        }
        for (Integer i : numbers) {             // 반복문의 변수는 검사 대상에서 제외된다.
            r += q;
        }
    }
}

- properties

NameDefaultDescription
minimum3Number of characters that are required as a minimum for a variable name.

PrematureDeclaration

#usability #optimizations

rulesets/java/optimizations.xml/PrematureDeclaration

객체의 초기화 혹은 생성하기에 적합한 위치인지 점검하라.

Checks for variables that are defined before they might be used. A reference is deemed to be premature if it is created right before a block of code that doesn’t use it that also has the ability to return or throw an exception.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/optimizations/PrematureDeclarationRule.html

public int getLength(String[] strings) {
  
  int length = 0;   // 적합하지 않은 위치의 객체 생성

  if (strings == null || strings.length == 0) return 0;
  
  for (String str : strings) {
    length += str.length();
  }

  return length;
}

ShortClassName

#usability #naming

rulesets/java/naming.xml/ShortClassName

클래스 이름을 minimum 설정보다 짧게 하지마라.

Short Classnames with fewer than e.g. five characters are not recommended.

- properties

NameDefaultDescription
minimum5Number of characters that are required as a minimum for a class name.

UseObjectForClearerAPI

#usability #controversial

rulesets/java/controversial.xml/UseObjectForClearerAPI

매개변수가 많을 경우 모델을 사용할 것을 고려해 본다.

When you write a public method, you should be thinking in terms of an API. If your method is public, it means other class will use it, therefore, you want (or need) to offer a comprehensive and evolutive API. If you pass a lot of information as a simple series of Strings, you may think of using an Object to represent all those information. You’ll get a simpler API (such as doWork(Workload workload), rather than a tedious series of Strings) and more importantly, if you need at some point to pass extra data, you’ll be able to do so by simply modifying or extending Workload without any modification to your API.

public class MyClass {
  public void connect(String username,
    String pssd,
    String databaseName,
    String databaseAdress)
    // Instead of those parameters object
    // would ensure a cleaner API and permit
    // to add extra data transparently (no code change):
    // void connect(UserData data);
    {

  }
}

SuspiciousConstantFieldName

#usability #naming

rulesets/java/naming.xml/SuspiciousConstantFieldName

자바명명규칙에 따라 변수 이름이 모두 대문자인 경우 상수로 판단한다. 그래서 해당 변수는 final 키워드를 추가해야 한다. 불변의 상태를 유지한다.

Field names using all uppercase characters - Sun’s Java naming conventions indicating constants - should be declared as final.

public class Foo {
 // this is bad, since someone could accidentally
 // do PI = 2.71828; which is actually e
 // final double PI = 3.16; is ok
  double PI = 3.16;
}

ShortMethodName

#usability #naming

rulesets/java/naming.xml/ShortMethodName

메서드 이름은 minimum 설정보다 짧게 하지마라.

Method names that are very short are not helpful to the reader.

public class Foo {
 // this is bad, since someone could accidentally
 // do PI = 2.71828; which is actually e
 // final double PI = 3.16; is ok
  double PI = 3.16;
}

- properties

NameDefaultDescription
minimum3Number of characters that are required as a minimum for a method name.

MethodNamingConventions

#usability #naming

rulesets/java/naming.xml/MethodNamingConventions

메서드 이름은 항상 소문자로 시작해야 하며, 언더바_를 사용할 수 없다.

Method names should always begin with a lower case character, and should not contain underscores.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/naming/MethodNamingConventionsRule.html

public class Foo {
    public void fooStuff() {} // 좋음
    public void foo_stuff() {} // 나쁨
    public void FooStuff() {} // 나쁨
}

- properties

NameDefaultDescription
checkNativeMethodstrueCheck native methods

AvoidFieldNameMatchingTypeName

#usability #naming

rulesets/java/naming.xml/AvoidFieldNameMatchingTypeName

클래스 이름과 같은 이름의 변수를 사용하지 마라.

It is somewhat confusing to have a field name matching the declaring class name. This probably means that type and/or field names should be chosen more carefully.

선언 클래스 이름과 일치하는 필드 이름을 다소 혼란스러운 일이다. 이것은 형식 및 필드 이름을 더 신중하게 선택되어야 한다는 것을 의미한다.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/naming/AvoidFieldNameMatchingTypeNameRule.html

public class Foo extends Bar {
    int foo;    // 아마도 사용할 수 있는 더 나은 이름이 있을 것이다.
}

AvoidFieldNameMatchingMethodName

#usability #naming

rulesets/java/naming.xml/AvoidFieldNameMatchingMethodName

멤버변수 이름과 동일한 메서드 이름을 사용하지 마라.

It can be confusing to have a field name with the same name as a method. While this is permitted, having information (field) and actions (method) is not clear naming. Developers versed in Smalltalk often prefer this approach as the methods denote accessor methods.

이름과 같은 이름을 가진 필드 이름을 갖는 것은 혼동스러울 수 있다. 이 작업이 허용되는 동안(필드)및 조치(메서드)가 명확하게 명명되지 않습니다. Smalltalk에 익숙한 개발자는 종종 접근하는 방법을 선호하는 방법으로 이 접근법을 선호한다.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/naming/AvoidFieldNameMatchingMethodNameRule.html

public class Foo {
    Object bar;
    // bar는 데이터이거나, 혹은 둘 다인가?
    void bar() {
    }
}

BooleanGetMethodName

#usability #naming

rulesets/java/naming.xml/BooleanGetMethodName

boolean 를 반환하는 메서드의 이름은 is 시작해야한다. 단 프리미티브 타입인 경우에만 해당 한다.

Methods that return boolean results should be named as predicate statements to denote this. I.e, ‘isReady()’, ‘hasValues()’, ‘canCommit()’, ‘willFail()’, etc. Avoid the use of the ‘get’ prefix for these methods.

public boolean getFoo();    // 나쁨
public boolean isFoo();     // 좋음
public Boolean getFoo();    // 좋음
public boolean getFoo(boolean bar); // 괜찮음, 단 checkParameterizedMethods 설정이 true 인 경우

- properties

NameDefaultDescription
checkParameterizedMethodsfalseCheck parameterized methods

AvoidThrowingNullPointerException

#usability #strict exception

rulesets/java/strictexception.xml/AvoidThrowingNullPointerException

매개변수에 대한 예외를 발생시킬 경우 NullPointerException 보다 IllegalArgumentException 사용여부를 먼저 판단하라. 그리고 더 적합한 예외를 사용하라. NullPointerException 는 사용하지 마라.

Avoid throwing NullPointerExceptions. These are confusing because most people will assume that the virtual machine threw it. Consider using an IllegalArgumentException instead; this will be clearly seen as a programmer-initiated exception.

NullPointerExceptions을 던지지 말아라. 이것들은 가상 머신에서 그것을 던졌다고 사람들이 생각하기 때문에 혼란스러워 한다. 대신 IllegalArgumentException를 사용하는 것을 고려해 보십시오. 이것은 명확한 예외로 간주될 것입니다.

public class Foo {
  void bar() {
    throw new NullPointerException();
  }
}

AbstractNaming

#usability #naming

rulesets/java/naming.xml/AbstractNaming

추상클래스 이름은 Abstract 시작해야 한다.

Abstract classes should be named ‘AbstractXXX’.

추상 클래스는 'AbstractXXX'로 명명되어야 한다.

public abstract class Foo {} // 나쁨
public abstract class AbstractFoo {} // 좋음

AddEmptyString

#efficiency #optimization

rulesets/java/optimizations.xml/AddEmptyString

불필요한 빈 문자""를 사용하지 마라.

The conversion of literals to strings by concatenating them with empty strings is inefficient. It is much better to use one of the type-specific toString() methods instead.

빈 문자열로 문자열을 변환하여 문자열을 변환하는 것은 비효율적입니다. 대신에 toString( type-specific)방법 중 하나를 사용하는 것이 훨씬 낫다.

sb.append(URLEncoder.encode("" + c, charset)); // 나쁨
sb.append(URLEncoder.encode(String.valueOf(c), charset)); // 좋음

String s = "" + 123;                // 나쁨
String t = Integer.toString(456);   // 좋음

AppendCharacterWithChar

#efficiency #strings

rulesets/java/strings.xml/AppendCharacterWithChar

StringBuilder 혹은 StringBuffer 에서 문자열을 concat(+)으로 연결하지 마라.

Avoid concatenating characters as strings in StringBuffer.append.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/strings/AppendCharacterWithCharRule.html

StringBuilder sb = new StringBuilder();

sb.append(","); // 나쁨 char 사용하기
sb.append(','); // 좋음

sb.append("aaa" + "bbbb"); // 나쁨 concat(+) 을 사용하지 않기
sb.append("aaa").append("bbbb"); // 좋음

AvoidBranchingStatementAsLastInLoop

#efficiency #basic

rulesets/java/basic.xml/AvoidBranchingStatementAsLastInLoop

반복에서 Branching Statements (break 혹은 continue)을 마지막에 사용하지 마라.

Using a branching statement as the last part of a loop may be a bug, and/or is confusing. Ensure that the usage is not a bug, or consider using another approach.

루프의 마지막 부분으로서 분기문을 사용하는 것은 버그가 될 수 있으며 혼동이 될 수 있습니다. 사용법이 버그가 아니거나 다른 접근법을 사용하는 것을 고려해야 합니다.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/basic/AvoidBranchingStatementAsLastInLoopRule.html


// 나쁨
for (int i = 0; i < 10; i++) {
    if (i*i <= 25) {
        continue; // 생략할 수 있음.
    }
    break;
}

// 좋음
for (int i = 0; i < 10; i++) {
    if (i*i > 25) {
        break;
    }
}

관련링크 https://docs.oracle.com/javase/tutorial/java/nutsandbolts/branch.html

AvoidInstantiatingObjectsInLoops : 보류중

#efficiency #optimization

필수사항이 아니며, 판단하고 리팩토리한다.

rulesets/java/optimizations.xml/AvoidInstantiatingObjectsInLoops

반복문에 새로운 객체를 생성해야하는 지 다시 확인해라. 즉 외부에서 생성된 객체 혹은 생성하여 재사용할 수 있는 지 여부를 판단하라.

New objects created within loops should be checked to see if they can created outside them and reused.

루프 내에서 생성된 새로운 물체는 그들이 외부에서 생성하고 다시 사용할 수 있는지 알아보기 위해 점검해야 한다.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/optimizations/AvoidInstantiatingObjectsInLoopsRule.html

public class Something {
    public static void main( String as[] ) {  
        for (int i = 0; i < 10; i++) {
            Foo f = new Foo(); // 매번 생성되는 객체를 성능저하가 발생한다. 
        }
    }
}

관련링크 https://groups.google.com/forum/#!topic/ksug/ntQqi8l_6LY

FinalFieldCouldBeStatic

#efficiency #design

rulesets/java/design.xml/FinalFieldCouldBeStatic

상수는 static 키워드를 추가하라. final 키워드를 가진 멤버변수를 상수라고 한다.

If a final field is assigned to a compile-time constant, it could be made static, thus saving overhead in each object at runtime.

private final String delimiter = ","; // static 키워드를 추가한다.

private static final String delimiter = ","; // 좋음

LoggerIsNotStaticFinal

#efficiency #java-logging

rulesets/java/logging-java.xml/LoggerIsNotStaticFinal

Logger 객체는 static final 키워드를 추가하여 선언한다.

In most cases, the Logger reference can be declared as static and final.

대부분의 경우, Logger 참조는 static 과 final 로 선언될 수 있다.

private static Logger logger = LoggerFactory.getLogger(); // final 키워드를 추가한다.

private static final Logger logger = LoggerFactory.getLogger(); // 좋음

RedundantFieldInitializer

#efficiency #optimizations

rulesets/java/optimizations.xml/RedundantFieldInitializer

자바에서 프리미티브 타입은 기본값을 가지므로 다시 같은 값을 대입하지 마라.

Java will initialize fields with known default values so any explicit initialization of those same defaults is redundant and results in a larger class file (approximately three additional bytecode instructions per field).

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/optimizations/RedundantFieldInitializerRule.html

// 프리미티브 타입 기본값
public class C {
    boolean b   = false;    // examples of redundant initializers
    byte by     = 0;
    short s     = 0;
    char c      = 0;
    int i       = 0;
    long l      = 0;
    
    float f     = .0f;    // all possible float literals
    doable d    = 0d;     // all possible double literals
    Object o    = null;
    
    MyClass mca[] = null;
    int i1 = 0, ia1[] = null;
    
    class Nested {
        boolean b = false;
    }
}

// 예제
private boolean is = false; // 나쁨
private boolean is;          // 좋음
private boolean is = true; // 좋음

UnnecessaryLocalBeforeReturn

#efficiency #design

rulesets/java/design.xml/UnnecessaryLocalBeforeReturn

불필요한 지역변수를 생성하고 반환하지 마라.

Avoid the creation of unnecessary local variables

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/design/UnnecessaryLocalBeforeReturnRule.html

public class Foo {
   public int foo() {
     int x = doSomething(); // 불필요한
     return x;
     
     return doSomething(); // 좋음
   }
}

UnnecessaryWrapperObjectCreation

#efficiency #optimizations

rulesets/java/optimizations.xml/UnnecessaryWrapperObjectCreation

불필요한 래퍼 객체를 생성하지 마라.

기본형 타입(primitive type)wrapper class
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharater
booleanBoolean
voidVoid

Most wrapper classes provide static conversion methods that avoid the need to create intermediate objects just to create the primitive forms. Using these avoids the cost of creating objects that also need to be garbage-collected later.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/optimizations/UnnecessaryWrapperObjectCreationRule.html

public int convert(String s) {
  int i, i2;

  i = Integer.valueOf(s).intValue(); // 나쁨
  i = Integer.parseInt(s);           // 좋음

  i2 = Integer.valueOf(i).intValue(); // 나쁨
  i2 = i; // 좋음

  String s3 = Integer.valueOf(i2).toString(); // 나쁨
  s3 = Integer.toString(i2);        // 좋음

  return i2;
}

UseStringBufferForStringAppends

#efficiency #optimizations

rulesets/java/optimizations.xml/UseStringBufferForStringAppends

+= 연산자를 이용하여 문자열을 연결하는 횟수가 반복적인 경우 StringBuilder 혹은 StringBuffer 사용을 권장한다. 동기화가 필요한 경우(threadsafe) StringBuffer 사용한다.

The use of the ‘+=’ operator for appending strings causes the JVM to create and use an internal StringBuffer. If a non-trivial number of these concatenations are being used then the explicit use of a StringBuilder or threadsafe StringBuffer is recommended to avoid this.

This rule is defined by the following Java class: https://pmd.github.io/pmd-5.5.1/pmd-java/xref/net/sourceforge/pmd/lang/java/rule/optimizations/UseStringBufferForStringAppendsRule.html

public class Foo {
  void bar() {
    String a;
    a = "foo";
    a += " bar"; // 나쁨

   StringBuilder a = new StringBuilder("foo");
   a.append(" bar); // 좋음
  }
}


댓글 남기기
◀ PREV 1234567···25 NEXT ▶