본문 바로가기

Java/이펙티브 자바

(11)
이펙티브 자바 - 12 장 직렬화 자바 직렬화의 대안을 찾으라 자바 직렬화는 공격범위가 넓어 악의적으로 공격할 수 있는 요소가 많아 직렬화 사용을 주의해야한다. 직렬화를 사용하려면 자바 9 부터 추가 된 직렬화 필터 사용을 하자 허용된 클래스에만 역직렬화를 사용 할 수 있어서 더 안전하게 사용할수있다. Serializable을 구현할지는 신중히 결정하라 Serializable 를 구현 하는 순간 직렬화 가능한 클래스가 되지만, 릴리즈 후 변경이 힘들어진다 클래스의 내부 구현을 수정하면 직렬화 형태가 달라진다. 새로 변경된 클래스를 이전 버전에서 역직렬화 하게 되면 에러가 발생한다. (SerialVersionUID를 생성해두지 않으면 시스템이 런타임에 자동으로 생성하는데, 이 값이 객체가 변경이 되면 자동으로 변경이 되어버려서 버전이 다른..
이펙티브 자바 - 11장 동시성 공유 중인 가변 데이터는 동기화해 사용하라 synchronized 메서드나 블록을 한 스레드만 수행 할 수 있도록 하려면 synchronized 키워드를 사용하면 된다. 동기화 메서드나 블록에 들어간 스레드는 락의 보호하에 동작한다. 원자적 자바에서 long 과 double 을 제외한 변수(32bit)는 원자적이다. 즉, 동기화 없이 사용을해도 여러 스레드가 같은 변수를 수정하더라도 항상 정상적으로 값을 읽어오는게 보장된다. 하지만, 스레드가 필드를 읽을 때 항상 수정이 완전히 반영된 값을 얻는다 보장 하지만, 스레드가 저장한 값이 다른 스레드에 보이는가(visibillity)는 보장하지 않는다. 따라서, 원자적 데이터를 쓸때도 동기화 해야한다. 잘못된 코드 메인 스레드가 backgroundThread ..
이펙티브 자바 - 10장 예외 예외는 진짜 예외 상황에만 사용하라 예외를 잘못사용한예시다 jvm 구현자 입장에서 저렇게 작성된 코드에 최적화를 신경 쓰지 않았을 가능성이 크다. 예외는 예외 상황에서만 쓰자 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라 호출하는 쪽에서 복구할 것이라 여겨지면 검사 예외(Checked Exception) 을 던지고 아닌 경우엔 비검사 예외(Unchecked Exception)를 던지면 된다. 검사 예외는 try-catch 로 처리하거나 throw 를 이용해 바깥으로 전파시켜 메서드를 호출했을때 결과를 사용자에게 알려준다 Unchecked Exception 은 런타임 에러와 에러가 있는데, 프로그램에서 잡을 필요가 없거나 잡아도 실이 되는 경우다 복구가 불가능 할 수 있..
이펙티브 자바 - 9장 일반적인 프로그래밍 원칙 지역변수의 범위를 최소화하라 항상 사용할때 지역변수를 선언하자 지역변수의 범위를 최소화 할 수 있다. 그리고 지역변수는 선언과 함께 초기화 해줘야 헷갈리지 않는다. 하지만, 지역변수를 초기화 할 수 없다면, 초기화 가능 할때 해주면된다. try -catch 문은 예외다. try 블록 밖에서도 변수를 사용해야 하면 지역변수 선언은 try 문장 밖에서 하고 초기화는 try-catch 문 안에서 하면 된다. 반복문은 while 보다 for 문을 권장한다. for문이 지역변수의 범위를 더 최소화 할 수 있다. 전통적인 for 문보다는 for-each 문을 사용하라 단순히 반복 실행을 위해 루프 변수가 필요해진다. 불필요하고 잘못사용할 경우 오류가 발생할수있다. foreach를 권장한다. 라이브러리를 익히고 사용..
이펙티브 자바 - 8장 메서드 매개변수가 유효한지 검사하라 매개변수 validate 를 하지 않으면 Runtime 시에나 에러가 발생할수있다. 유효성 검사방법 Null 자바 7 부터는 Objects.requireNonNull 로 Null 검사를 쉽게 할 수 있다. 자바 9 부터는 Objects 의 checkFromIndexSize, checkFromToIndex, checkIndex 같은 메서드를 이용해 범위 검사도 할 수 있다. assert 사용 private 메서드라면 assert 를 사용하여 유효성 검사를 할 수 있다. 조건식을 만족하지 않으면 AssertionError 가 발생한다. 적시에 방어적 복사본을 만들라. Date 는 가변 매개변수다. 클래스가 클라이언트로부터 받는 매개변수가 가변이라면 반드시 방어적으로 복사를 해야한..
이펙티브 자바 - 7장 람다와 스트림 익명 클래스보다는 람다를 사용하라. 람다식은 추상 메서드 하나인 인터페이스의 인스턴스라고 할 수 있다. 람다보다는 메서드 참조를 사용하라 람다 보다는 짧고 명료한 메서드 참조를 사용해라 하지만, 메서드 참조가 모든 경우에 좋은 건 아니다. 클래스 이름이 너무 길거나, 메서드 이름이 무슨의미인지 명확하지 않은 경우엔 람다가 더 좋은 선택 일 수 있다. 표준 함수형 인터페이스를 사용하라. 위 6개를 알면 나머지를 유추하기 쉽다. ex. Unary -> 단항 Binary -> 이항.. 예를들어, BiFunction 을 보면 이항 Function으로 볼 수 있다. T,U 로 인수가 2개 들어오면 R 로 타입이 다른 리턴 값을 내보낼수있다. 와 같은 식으로 사용된다. 흔치는 않지만 직접 함수형 인터페이스를 구현하..
이펙티브 자바 - 6장 열거타입과 애너테이션 int 상수 대신 열거 타입을 사용하라. 상수대신 Enum 을 사용하자. 훨씬 안전하고 강력하다 각 상수를 특정 데이터와 연결하거나 상수마다 다르게 동작하게 할때 생성자나 메서드가 필요하다. switch 문 대신 상수별 메서드 구현을 사용. ordinal 메서드 대신 인스턴스 필드를 사용하라. 열거형에서 몇번째인지를 반환하는 ordinal 메서드를 사용하지말자 .ordinal 은 enum base 자료구조(EnumSet, Enum Map)에서 쓰이기 위해 만들어진 것 필드에 값을 넣어서 사용해주는게 맞다 비트 필드 대신 EnumSet을 사용하라. 과거에는 비트를 이용새 합집합, 교집합 같은 집합 연산을 효율적으로 할 수 있었지만, 비트 결과는 해석하기가 어렵다. 또한, 비트 필드에 포함된 원소를 순회하기..
이펙티브 자바 - 5장 제네릭 raw type은 사용하지 마라 raw type? 타입 매개변수 가 있을때 제네릭 클랫, 제네릭 인터페이스라 한다. List 이걸 제네릭 타입이라고 한다. 제네릭 타입을 정의 할때 raw type 도 정의 되는데 여기선 List 가 raw type 이다. 매개변수를 쓰지 않고 사용한 경우 이것은 제네릭이 도입 되기전의 호환성을 위해 쓸 수 있는것 왜 사용하면 안될까? 컴파일단에서 에러를 발견하지 못한다. 런타임에서 오류가나서 컴파일러의 검사를 사용하지 못한다. List arrayList = new ArrayList(); 로 제네틱 타입이 없는 경우를 만들었을때 arrayList.add("Test") 를 넣으면 컴파일러가 걸러내지 못한다. 타입 세이프가 없는 셈이된다. 반면에, List arrayList ..