JAVA
규칙 64 - 실패 원자성 달성을 위해 노력하라.
예외가 발생한 다음에도 기존에 사용하던 객체의 상태가 그대로 유지되는 것이 좋다.쉽게 이야기하면, 메서드 호출이 정상적으로 처리되지 못한 객체의 상태는 메서드 호출 전 상태와 동일해야한다. 이런 속성을 만족하는 메서드는 실패 원자성(failure atomicity)을 갖추었다고 한다. 이런 실패원자성을 해소하기 위한 방법을 알아보자. 먼저 간단하게 변경 불가능 객체로 설계하는 것이다.-> 왜냐하면 원자성이 있는 객체는 생성된 이후에는 변경되지 않기 때문에 오류가 발생한다고 해도 원자성이 깨지지 않는다. 그럼 변경 가능한 객체의 경우 어떻게 해야할까?-> 이는 실제 연산을 수행하기전에 인자 유효성을 미리 검사하는 방법이다. (객체가 변경되기 전에 예외를 발생시켜 발생하는 것을 막는것이다.) 아래 예를 살펴..
Java List 인터페이스 중 CopyOnWriteArrayList 소개
자바에는 크게 4개의 List 인터페이스를 구현한 클래스가 있다. - Vector, ArrayList, LinkedList, CopyOnWriteArrayList 그 중 가장 생소한 이름이 있는데 CopyOnWriteArrayList이다. CopyOnWriteArrayList는 그냥 ArrayList랑 다르길래 화려한 이름을 가지고 있는걸까? ArrayList vs CopyOnWriteArrayList 일반 ArrayList의 경우 스레드에 안전하게 설게되어 있지 않기때문에 만약 스레드 처리가 필요한 List의 경우에 Vector를 사용하거나 ArrayList에 synchroized를 사용하여 처리하였다. 하지만 자바 1.5부터 있던 CopyOnWriteArrayList를 쉽게 이문제를 해결할 수 있다...
규칙 63 - 어떤 오류인지를 드러내는 정보를 상세한 메시지에 담으라.
개발을 진행하다보면 예기치 못한 상황에서 에러가 자주 발생한다. 에러가 발생하는 것을 다 알고 차단할수있다면 정말 바람직한 프로그램이라고 할 수있을 것이다.하지만 그럴수가 없기때문에 에러를 관리하고 효율적으로 에러정보를 전달하는것이 중요하다. 정확한 에러정보를 전달하는것이 빠르게 문제를 해결하는 실마리가 될것이다.그래서 에러가 발생되었을 때 오류의 상세 메시지에 예외에 관련된 모든 인자와 필드값을 포함시켜야 한다. 예를 들어, IndexOutOfBounds Exception의 경우 해당 범위를 벗어난 인자값과 하한과 상한값도 포함되어있어야 한다. 그러면 정확히 어떻게 오류가 발생된 것인지 알기가 쉬워진다. 하지만 관련된 데이터를 담는 것이 중요하지만 잘못사용하면 별로 도움이 되지 않을 수 있다.그리고 이..
규칙 62 - 메서드에서 던져지는 모든 예외에 대해 문서를 남겨라.
메서드를 올바르게 사용하려면 메서드에서 던져지는 예외에 대한 설명이 문서에 있어야 한다. 그리고 메서드가 던질수있는 모든 무점검 예외까지 선언할 필요는 없지만 점검지점 예외들과 마찬가지로주의해서 문서로 남겨놓으면 좋다. 특히 Javadoc @throws 태그를 사용해서 메서드에서 발생 가능한 모든 무점검 예외에 대한 문서를 남겨야 한다. 하지만 메서드 선언부의 throws 뒤에 무점검 예외를 나열하지는 말아야 한다. 요약하자면 메서드가 던질 가능성이 있는 모든 예외를 문서로 남겨라. 점검지점 예외, 무점검 예외도 남겨라. 이를 지키지 않으면 해당 API를 사용하는 다른사람들이 효과적으로 사용하는게 어려워진다. 출처 : 조슈아 블로크, 『 Effective Java 2/E』, 이병준 옮김, 인사이트(201..
규칙 61 - 추상화 수준에 맞는 예외를 던져라
메서드가 하는 일과 관련성이 없는 예외가 메서드에서 발생하면 디버깅하기 어렵거나 관리하기 어려울 수 있다. 이는 추상화 수준이 낮은 곳에서 발생한 예외를 그대로 밖으로 전달하면 이런일이 발생한다. 이런 문제를 해결하기 위해서 상위계층에서는 하위계층에서 발생하는 예외를 반드시 받아서 상위 계층 추상화 수준에 맞는 예외로 바꿔서 던져야한다. 이를 예외 변환(exception translation)이라고 한다. 예를 들어 몇가지 사례를 살펴보자. 우선 AbstractSequentialList 클래스를 살펴보자. 이 클래스의 get 메서드의 명세를 보면 예외가 발생되었을 때 예외 변환을 해서 보내달라는 것을 확인할 수 있다. 12345678910111213141516 /** * Returns the elemen..
기타 자바8에 추가된 편리기능
String.joiner 구분자를 이용해서 입력된 데이터를 구분해서 String으로 반환 123456789101112131415161718192021public class Java8Test { public static void main(String args[]) { StringJoiner sj = new StringJoiner(","); sj.add("babo"); sj.add("wedul"); sj.add("pnp"); System.out.println(sj.toString()); // 2, 3번재 매개변수를 이용하여 prifix, suffix를 붙힐 수 있다. sj = new StringJoiner(",", "자기소개 -- ", " -- 끝"); sj.add("babo"); sj.add("wedul"..
Java8 람다식의 지연실행 (Lazy Programming)
지연실행 -> 람다를 이용하면 필요할때만 호출해서 사용할 수 있는 Lazy Programming을 구현 할 수 있다. 기존에 다음과 같이 사용하면 당장 사용하지 않아도 실행이 되는 문제가 있었다. 1234567891011121314151617181920212223public class Heavy { Heavy() { System.out.println("Heavy created"); } } Hodler 클래스 Holder 클래스는 heavy 클래스를 포함하고 있다. public class Holder { public Holder() { System.out.println("Holder created"); } Heavy heavy = new Heavy(); public Heavy getHeavy() { ret..
Java8 함수형 인터페이스 만들어서 사용하기
Java8 함수형 인터페이스 만들어서 사용하기 함수형 인터페이스 사용 -> 정의한 함수형 인터페이스를 람다식을 이용하여 사용할 수 있다. 12345678910111213141516171819// 함수형 인터페이스 선언 // 함수형 인터페이스를 만들고자 할 경우에는 @FunctionalInterface 애노테이션을 붙혀야 한다. @FunctionalInterfacepublic interface WedulInterface { public void print(int x);} public static void main(String args[]) { WedulInterface wedul = new WedulInterface() { @Override public void print(int x) { System.ou..
자바 8에서 java.util.function 패키지에 추가된 기본 함수형 인터페이스 정리
자바 8에서 java.util.function 패키지에 추가된 기본 함수형 인터페이스 정리 Function => T를 입력으로 R을 출력하여 반환 1234567891011121314151617public class Java8Test { public static void main(String args[]) { Function mapStrToInt = new Function() { public Integer apply(String str) { if (str == "wedul") { return 1; } return 2; } }; List testData = Arrays.asList("wedul","dd","babo"); testData.stream().map(mapStrToInt).forEach(System..
Java8 스트림을 이용한 데이터 추출
스트림에 있는 데이터를 List, String, Set등 다양한 형태로 변경하여 추출 할 수 있다. toArray Stream.toArray는 Object[]를 리턴한다. 올바른 타입의 배열을 원하는 경우 다음과 같이 배열 생성자를 전달한다. String[] result = words.toArray(String[]::new); Collect 메소드 - Collect : 종료 작업으로 인자로 받은 형태의 데이터 타입으로 결과물을 생성한다. - Collect는 병렬화를 지원한다. 또한 공급자, 누산자, 결합자를 기본적인 파라미터로 받으며 이는 Collectors라는 클래스를 통해 간편하게 정의하여 사용할 수 있다. 1) List, set, String 1234567Stream data = Stream.of(..