Development/JAVA
[디비파기 | PMD] AvoidInstantiatingObjectsInLoops 외 3건
마즈다
2016. 4. 11. 09:35

AvoidInstantiatingObjectsInLoops
우선순위 : 3
New objects created within loops should be checked to see if they can created outside them and reused.
Loop 안에서 객체의 인스턴스를 생성할 때는 Loop 밖에서 생성한 후 재사용 가능한지
확인하라
샘플코드
| public class Something { public static void main( String as[] ) { for (int i = 0; i < 10; i++) { Foo f = new Foo(); // Avoid this whenever you can it's really expensive } } } |
부연설명
잘 아다시피 instance를 생성한다는 것은 메모리를 사용한다는 의미다.
루프 안에서 객체의 인스턴스를 생성한다는 것은 곳 루프가 도는 만큼 메모리를
소비하게 된다는 이야기다. 하지만 이 룰에 강제성을 두지 않은 이유는 참조타입의
변수 각각에 서로 다른 값을 가지게 해야 할 경우 루프 밖에서 인스턴스를 생성한 후
루프 안에서 값을 할당하게 되면 모든 인스턴스가 동일한 값을 가지게 되어
의도한 대로 작동하지 않게 되기 때문이다. 따라서 이 룰은 잘 판단을 하여 사용해야 한다.
SimplifyStartsWith
우선순위 : 3
Since it passes in a literal of length 1, calls to (string).startsWith can be rewritten using (string).charAt(0) at the expense of some readability.
문자열의 길이가 1이라면 startsWith 메소드를 사용하는 것보다 charAt(0)을 사용하는 것이
더 효율적이다.
샘플 코드
| public class Foo { boolean checkIt(String x) { return x.startsWith("a"); // suboptimal } boolean fasterCheckIt(String x) { return x.charAt(0) == 'a'; // faster approach } }
|
UseStringBufferForStringAppends
우선순위 : 3
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.
문자열을 합치기 위한 ‘+=‘ 연산은 JVM에서 내부적으로 StringBuffer를 생성하여
사용한다. 따라서 통상적인 범위를 넘어서는 문자열 연결이라면 명시적으로
StringBuilder나 혹은 thread에 안정적인 StringBuffer(threadsafe한 대신
조금 느림)를 사용하도록 권고한다.
샘플코드
| public class Foo { void bar() { String a; a = "foo"; a += " bar"; // better would be: // StringBuilder a = new StringBuilder("foo"); // a.append(" bar); } } |
부연설명
PMD에서 뿐만 아니라 일상적인 코딩에서도 논란이 많은 룰입니다.
이미 내부적으로 StringBuffer를 사용하므로 그냥 += 연산자를 사용해도 되지
않느냐는 말들도 참 많이 합니다. 룰 설명에도 ‘통상적인 범위를 넘어서는’이라는
전제를 달고 있고…
현재까지의 가장 합리적인 절충안은 적어도 loop안에서는 += 사용을 지양하는 정도가
되겠네요.
오히려 += 연산자를 쓰느냐 마느냐보다는 StringBuffer와 StringBuilder를 선별해서
사용하는데 주의를 기울여야 할 것 같습니다.
UseArraysAsList
우선순위 : 3
The java.util.Arrays class has a “asList” method that should be used when you want to create a new List from an array of objects. It is faster than executing a loop to copy all the elements of the array one by one.
배열(Arrays)을 List로 변환하는 경우 Array 클래스에 있는 asList 메소드를 이용하는 것이
루프문을 통해 하나하나 복사하는 것보다 더 빠르므로 asList 메소드를 사용하는 것이 좋다.
샘플 코드
| public class Test { public void foo(Integer[] ints) { // 아래의 두 경우는 모두 느리며 간단하게 한 문장으로 // List l = Arrays.asList(ints);로 사용하는 것이 더 낫다. List l= new ArrayList(10); for (int i=0; i< 100; i++) { l.add(ints[i]); } for (int i=0; i< 100; i++) { l.add(a[i].toString()); // PMD에 걸리지는 않지만 늦다. } } } |