한번 소비된 Stream pipeline은 재사용해선 안됩니다
Stream 연산은 중간 연산(intermediate)과 터미널 연산(terminal)으로 나뉘며, 결합되어 Stream pipeline을 만듭니다.
터미널 연산(terminal)을 수행하면, 이미 스트림 파이프라인이 사용된 것으로 간주되어 다시 사용할 수 없습니다.
이러한 재사용은 예상치 못한 결과를 만들 수 있습니다.
규칙을 어긴 코드
Stream<Widget> pipeline = widgets.stream().filter(b -> b.getColor() == RED);
int sum1 = pipeline.sum();
int sum2 = pipeline.mapToInt(b -> b.ge...
Stream 중간(Intermediate) 연산은 사용되지 않은 채 남겨져선 안됩니다.
스트림 연산에는 두 가지 유형이 있습니다.
다른 스트림을 반환하는 중간 연산(intermediate)과 스트림이 아닌 다른 값을 반환하는 터미널 연산(terminal)입니다.
중간 연산(intermediate)은 느립니다.
따라서 스트림은 터미널 연산(terminal)을 수행하지 않는 한 실제로 코드를 실행하지 않습니다.
결과적으로 중간 연산(intermediate)의 값이 터미널 연산(terminal)에 의해 사용되지 않으면, 아무런 가치가 없는 코드가 될 확률이 높으며, 이는 거의 확실한 에러 상황입니다.
규칙을 어긴 코드
widgets.stream().filter(b -> b.getColor() ==...
"Stream.peek" 사용은 조심해야 합니다
JavaDocs에 따르면 Stream 중간 연산(intermediate) 중, java.util.Stream.peek()에는 이런 내용이 있습니다.
“java.util.Stream.peek()은 디버깅을 지원하기 위해 존재합니다”
다른 Stream 중간 연산(intermediate)과는 다르게 peek()은 최적화되는 과정에서 실행하지 않고 넘어갈 수도 있다는 의미입니다.
즉, peek()은 Stream 에서 얘기치 않은 동작을 만들 수 있습니다.
어떤 element 만 실행된다거나, 아니면 아예 실행되지 않는다거나 같이요.
따라서 peek()을 무분별하게 사용하면 오류가 발생하기 쉬운 코드가 될 수 있습니다....
"Map.get"이나 value 테스트는 단일 메서드 호출을 사용하여야 합니다.
map 안의 값을 변경하거나 새로 만들기 전에, 데이터가 이미 있는지 확인하기 위하여, java.util.Map.get() 결과를 null이랑 비교하거나, java.util.Map.containsKey()를 사용하는 경우를 흔히 볼 수 있습니다.
하지만 java.util.Map에는 computeIfPresent()와 computeIfAbsent()이라는 훌륭한 대안 메소드가 API 로 존재합니다.
가독성 좋은 코드와 깨끗한 코드가 되기 위해 이 인터페이스들을 대신 사용해주세요.
참고: 이 규칙은 프로젝트의 sonar.java.source의 값이 8보다 낮은 경우(java8) 검사하지 않습니다.
규칙을 어긴 코드...
Java 8에서 "Files.exists"는 사용되선 안됩니다.
Files.exists 메서드는 JDK 8에서 성능이 현저히 떨어지는것으로 알려져있습니다.
실제로 존재하지 않는 파일을 검사하는 데 이 메소드를 사용할 경우, 애플리케이션의 속도가 상당히 느려질 수 있습니다.
java.nio.file 패키지 아래에 있는 Files.notExists, Files.isDirectory 및 Files.isRegularFile도 마찬가지입니다.
참고: 이 규칙은 프로젝트의 sonar.java.source의 값이 8보다 낮은 경우(java8) 검사하지 않습니다.
규칙을 어긴 코드
Path myPath;
if(java.nio.file.Files.exists(myPath)) { // ...
데이터베이스 쿼리는 injection 공격에 취약해서는 안됩니다.
유저가 제공하는 URL 파라미터와 같은 데이터는, 항상 신뢰할수 없고, 손상된 데이터로 간주해야 합니다.
손상된 데이터를 통해 SQL 쿼리를 생성하는 것은, 쿼리의 초기 의미와는 다르게 공격자들이 특별하게 조작된 값을 삽입할 수 있게 합니다.
데이터베이스 쿼리 인젝션 공격이 성공하면 데이터베이스의 민감한 정보들을 읽고, 수정하고, 삭제할 수 있으며 심지어는 데이터베이스를 종료하거나, 임의의 OS 커맨드를 실행할 수 있습니다.
일반적으로, 해결책은 prepared statements 를 사용하고, SQL 쿼리 파라미터를 setString 과 같은 전용 메소드를 사용해 사용자가 제공한 데이터를 적절하게 처리한 채로 ...
Value-based 객체는 Serialize되선 안됩니다.
⚠️주의⚠️: 해당 문서는 역자의 능력 부족으로 인해 의역이 많이 들어갔습니다. Contribution을 환영합니다.
문서에 따르면,
value-based class에서 같은 값을 가리키는 두개의 참조 객체를 다르게 구분한다면, 예상치 못한 문제가 발생할 수 있습니다. 특히, 그런 상황에서 synchronization 하거나 hash 값으로 동등성을 체크하려 한다거나, 직렬화 하려할 때 등에 문제가 발생합니다.
예를들면, Foo를 value-based class라고 생각해주세요.
Foo[] arr = new Foo[2];
arr[0] = new Foo(0);
arr[1] = new Foo(0);
...
Value-based 클래스들이 lock을 하는데 사용되선 안됩니다
⚠️주의⚠️: 해당 문서는 역자의 능력 부족으로 인해 의역이 많이 들어갔습니다. Contribution을 환영합니다.
문서에 따르면,
value-based class에서 같은 값을 가리키는 두개의 참조 객체를 다르게 구분한다면, 예상치 못한 문제가 발생할 수 있습니다. 특히, 그런 상황에서 synchronization 하거나 hash 값으로 동등성을 체크하려 한다거나, 직렬화 하려할 때 등에 문제가 발생합니다.
이는 value-based class가 단순히 value 타입의 wrapper가 되는 것을 의도하고 만들어졌기 때문입니다.
value-based class의 인스턴스
접근...
전체 글 239개, 30 페이지