반응형

Effective Java 46

[Effective Java] Item57. 지역변수의 범위를 최소화하라

지역변수의 유효범위를 최소로 줄이면 코드 가독성, 유지보수성이 높아지고 오류 가능성을 낮출 수 있습니다. 가장 처음 쓰일 때 선언 선언과 동시에 초기화 메서드를 작게 유지하고 한 가지 기능에 집중 반복문의 경우 반복 변수의 값을 반복문 종료 후에도 사용할 것이 아니라면 for문을 사용하는 것이 보통은 낫습니다.

카테고리 없음 2022.07.30

[Effective Java] Item56. 공개된 API요소에는 항상 문서화 주석을 작성하라

문서화 주석은 API를 문서화 하는 가장 효과적인 방법이므로 공개 API라면 이에대한 설명을 빠짐없이 달아야 합니다. 메서드용 문서화 주석 메서드와 클라이언트 사이의 규약을 명료하게 기술합니다. 사욕용으로 설꼐된 클래스의 메서드가 아니라면 무엇을 하는지 기술합니다.(how가 아닌 what) 메서드 호출 전제조건을 모두 기술합니다. 메서드가 성공적으로 수행된 후에 만족해야 하는 사후조건을 모두 기술합니다. 전제조건은 @throws태그로 비검사 예외를 선언하여 암시적으로 기술하며 @param태그를 이용해 조건에 영향을 받는 매개변수도 기술합니다ㅣ. 메서드 계약(contract) @param 태그를 달아 메서드 계약을 완벽하게 기술합니다. 반환타입이 void가 아니라면 @return태그를 답니다. @retur..

카테고리 없음 2022.07.30

[Effective Java] Item55. 옵셔널 반환은 신중히 하라

메서드가 특정 조건에서 값을 반환할 수 없을 때 예외를 던지거나, null을 반환합니다. 예외는 진짜 예외적인 상황에서만 사용해야하며 예외를 생성할 때 스택 추적 전체를 캡처하므로 비용도 상당합니다. null을 반환하면 메서드를 호출할 때 마다 null처리는 해야하며 그렇지 않으면 언젠가는 NullPointerException이 발생할 수 있습니다. Optional 자바 8에서는 하나의 선택지가 더 생겼습니다. Optional는 null이 아닌 T가 있거나 없을 수 있습니다. Optional은 원소를 최대 1개 가질 수 있는 불변컬렉션입니다. (실제로는 Collection를 구현하지는 않았습니다.) public static E max(Collection c) { if (c.isEmpty()) throw ..

카테고리 없음 2022.07.30

[Effective Java] Item46. 스트림에서는 부작용 없는 함수를 사용하라

Map freq = new HashMap(); try(Stream words = new Scanner(file).tokens()) { words.forEach(word -> { freq.merge(word.toLowerCase(), 1L, Long::sum); }); } forEach 내부에서 외부 상태(freq)를 수정하므로 순수 함수가 아닙니다. Map freq; try(Stream words = new Scanner(file).tokens()) { freq = words.collect(groupingBy(String::toLowerCase, counting())); } Collector collect 메서드는 스트림 종료작업으로 Collector 타입의 인자를 받아서 처리합니다. java.util...

[Effective Java] Item45. 스트림은 주의해서 사용하라

스트림(Stream) API? 스트림 API는 다량의 데이터 처리 작업을 위해 JDK8부터 추가되었습니다. 스트림은 데이터 원소의 유한 혹은 무한 시퀀스를 의미하며, 스트림 파이프라인은 이 원소들로 수행하는 연산단계를 표현하는 개념입니다. 스트림 안의 데이터 원소들은 기본적으로 객체 참조타입이며, int, long, double의 세가지 기본타입을 지원하기도 합니다. 스트림 파이프라인 public static void main(String[] args) { List.of("apple", "banana", "car") // 리스트 .stream() // 소스 스트림 .filter(s -> s.startsWith("b")) // 중간 연산 .forEach(System.out::println); // 종단 연..

[Effective Java] Item 44. 표준 함수형 인터페이스를 사용하라

표준 함수형 인터페이스 java.util.function패키지에는 총 43개의 함수형 인터페이스를 제공합니다. 이 중 6개 정도만 기억하면 나머지도 유추하기 쉽습니다. UnaryOperator T apply(T t): 반환값과 인수의 타입이 같은 함수, 인수는 1개. String::toLowerCase BinaryOperator T apply(T t1, T t2): 반환값과 인수의 타입이 같은 함수, 인수는 2개. BigInteger::add Predicate boolean test(T t): 한 개의 인수를 받아서 boolean을 반환하는 함수. Collection::isEmpty Function R apply(T t): 인수와 반환 타입이 다른 함수. Arrays::asList Supplier T g..

[Effective Java] Item43. 람다보다는 메서드 참조를 사용하라

메서드 참조 List.of(1, 2, 3, 4).forEach(i -> System.out.println(i)); List.of(1, 2, 3, 4).forEach(System.out::println); // 메서드 참조 메서드 참조를 사용할 때 주의사항 대부분의 경우 람다에 비해 코드가 간결하고 명확해지지지만 람다에서 사용하는 매개변수 이름이 좋은 가이드가 된다면 코드가 더 길더라도 오히려 읽기가 더 쉬워질 것입니다. 또한, 메서드의 이름이 너무 길다면 오히려 람다가 더 간결해 질 수 있습니다. service.execute(() -> action()); service.execute(GoshThisClassNameIsHumongous::action); // 메서드 참조 메서드 참조의 유형 정적 메서드 참..

[Effective Java] Item42. 익명 클래스보다는 람다를 사용하라

람다의 장점 람다식은 메서드가 하는 일을 보다 간결하고 읽기 쉽게 표현합니다. 익명 클래스로 작성된 코드입니다. Collection.sort(words, new Comparator() { public int compare(String s1, String s2){ return Integer.compare(s1.length(), s2.length()); } }); 람다식으로 바꾸면 Collection.sort(words, (s1,s2) -> Integer.compare(s1.length(), s2.length())); 열거 타입에서의 람다 public enum Operation { PLUS("+") { public double apply(double x, double y) { return x + y; } }..

[Effective Java] Item41. 정의하려는 것이 타입이면 마커 인터페이스를 활용하라

마커 인터페이스 일반적인 인터페이스와 동일하지만 아무 메서드도 선언하지 않은 형태의 인터페이스입니다. 자신을 구현하는 클래스가 특정 속성을 가짐을 표시하기 위해 사용합니다. 대표적인 마커 인터페이스로는 Serializable, Cloneable 등이 있습니다. 마커 애너테이션과의 비교 마커 인터페이스의 장점 마커 인터페이스는 이를 구현한 클래스의 인스턴스들을 구분하는 타입으로 사용할 수 있습니다. ObjectOutputSteam.writeObject메서드의 경우 Serializable을 구현하지 않은 경우 NotSerializableException예외를 발생시킵니다. 마커 애너테이션도 Java Reflection을 이용하여 같은 기능을 할 수 있습니다. @MySerializable public clas..

[Effective Java] Item40. @Override 애너테이션을 일관되게 사용하라

@Override @Override 애너테이션은 메서드 선언에만 달 수 있으며, 해당 메서드가 상위 타입의 메서드를 재정의했다는 것을 알려줍니다. 붙이지 않아도 컴파일 오류가 나지 않지만 버그를 예방할 수 있기 때문에 사용하는 것이 좋습니다. @Override를 사용하지 않으면? public class MyClass { private final int a; public MyClass(int a) { this.a = a; } public boolean equals(MyClass m) { return m.a == a; } public int hashCode() { return a; } public static void main(String[] args) { Set set = new HashSet(); for..