전체 글

명명 패턴이란, 변수나 함수의 이름을 일관된 방식으로 작성하는 패턴.예를 들어 JUnit은 버전 3까지 테스트 메서드 이름을 test로 시작하게 하였다. testMethod()하지만 이 방식은 단점이 크다. 첫 번째 단점, 오타가 나면 안된다. tetsMethod로 잘못 작성하면 테스트 무시하고 지나간다.두 번째 단점, 올바른 프로그램 요소에서만 사용되리라 보증할 방법이 없다. (즉, 메서드에서만 test로 시작하는 명명을 하리라 보증할 방법이 없다는 것) 메서드가 아닌 클래스 이름을 test로 시작하게 지어서 넘겨주면 개발자는 이 클래스에 정의된 테스트 메서드들이 수행되길 바랬지만 JUnit은 클래스 이름에 관심이 없기에 경고도 띄우지 않은 채 테스트들은 수행되지 않는다.세 번째 단점, 프로그램 요소를..

배열 vs 리스트 첫 번째 차이,배열은 공변이다. -> Sub가 Super의 하위 타입이면, Sub[]는 Super[]의 하위타입이다.제네릭은 불공변이다. -> List와 List는 서로 다른 타입이다. 문제는 배열에 있다.public static void main(String[] args) { Object[] objects = new Long[1]; objects[0] = "haha";}Exception in thread "main" java.lang.ArrayStoreException: java.lang.StringLong 배열에 String을 넣으려고 하니 런타임 에러가 터진다. ArrayStoreException : Thrown to indicate that an attempt has ..


5장 들어가기 전에, 제네릭을 지원하기 전에는 컬렉션에서 객체를 꺼낼 때마다 형변환을 해야 했다.public static void main(String[] args) { List list = new ArrayList(); list.add(1); int get = (Integer) list.get(0); String str = (String) list.get(0);}*런타임 예외 발생java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.lang.String위와 같은 코드는 런타임 예외가 발생한다. 런타임 에러는 프로그램 실행 중 발생하기 때문에 크리티컬한 이슈를 발생시킬 수 있을 뿐만 아니라..

1. 추상 클래스 vs 인터페이스 가장 큰 차이는 추상 클래스가 정의한 타입을 구현하는 클래스는 반드시 추상 클래스의 하위 타입이 되어야 한다는 점이다. 추상 클래스 방식은 새로운 타입을 정의하는 데 커다란 제약을 안는 셈이다. 반면 인터페이스는 제대로 규약을 지켜서 구현했다면 모두 같은 타입으로 취급된다. 즉, 인터페이스는 같은 타입으로 확장이 가능하지만, 추상 클래스는 단일 상속만 가능하기 때문에 확장에 불리하다. 즉, 상속받은 하나의 부모 클래스로밖에 변경이 불가능함. 다른 타입으로 될 수가 없음. 인터페이스는 믹스인(mixin) 정의에 안성맞춤이다.* 믹스인이란? 클래스가 구현할 수 있는 타입(=인터페이스라고 생각하면 됨)으로, 믹스인을 구현한 클래스에 원래의 '주된 타입' 외에도 특정 선택적 ..

상위 클래스와 하위클래스를 모두 '같은 프로그래머'가 통제하는 '패키지 안'이라면 상속은 안전하다. 하지만 일반적인 구체 클래스를 패키지 경계를 넘어, 즉 다른 패키지의 구체 클래스를 상속하는 일은 위험하다. (클래스 -> 클래스 상속) 메서드 호출과 달리 상속은 캡슐화를 깨뜨린다.상위 클래스는 릴리스마다 내부 구현이 달라질 수 있다 -> 이를 상속하는 하위 클래스에 오동작 등 영향을 줄 수 있다. 문제 1HashSet(구체 클래스)을 상속한 MyHashSet(구체 클래스)import java.util.Collection;import java.util.HashSet;public class MyHashSet extends HashSet { private int addCount = 0; @Over..

Object에서 final이 아닌 메서드는 모두 재정의를 염두에 두고 설계된 것이라 재정의 시 지켜야 하는 일반 규약이 명확히 정의되어 있다. equals() 는 재정의가 쉬워보이지만 함정이 도사리고 있다.. 회피하는 길은 아예 재정의를 하지 않는 것이다. 그러면 오직 본인 자신과만 같게 된다. 왜냐하면 Object의 equals()는 주소값을 비교하기 때문이다.Object.classpublic boolean equals(Object obj) { return (this == obj);} 다음과 같은 상황 중 하나에 해당하면 재정의 안하는 것이 좋다.각 인스턴스가 본질적으로 고유함. -> ex)Thread처럼 값을 표현하는 것이 아닌 동작하는 개체를 표현하는 클래스. -> 동작하는 개체는 고유할 수 ..


InputStream, OutputStream, java.sql.Connection은 close()를 통해 직접 닫아줘야 한다. 왜?? 알다시피 java에는 gc가 존재한다. 힙영역에서 참조되지 않는 객체를 조사하고 제거하는 역할을 진행한다.그래서 따로 메모리 해제를 하지 않고 java를 사용해왔다.하지만 왜 위와 같은 클래스들은 따로 close()를 호출해줘야하는 것일까? 파일, 네트워크 연결, 데이터베이스 는 JVM 힙 영역에 올라가는 객체가 아니다. 운영체제의 리소스이다.먼저 운영체제의 Stream을 알아야 한다. 즉, 스트림은 프로그램(JVM)밖에 있는 외부 자원이다. JVM과 외부 통신을 통해 DB 연결, 네트워크 통신, 파일 디스크립터 등을 진행하는 것이다. 그래서 JVM 내부의 GC가 작동하..


참고 자료 : https://medium.com/@syedharismasood4/building-reliable-microservices-with-the-transactional-outbox-pattern-in-spring-boot-952d96f8b534https://medium.com/@egorponomarev/outbox-pattern-in-spring-boot-8e8cf116f044https://medium.com/@greg.shiny82/%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%94%EB%84%90-%EC%95%84%EC%9B%83%EB%B0%95%EC%8A%A4-%ED%8C%A8%ED%84%B4%EC%9D%98-%EC%8B%A4%EC%A0%9C-%EA%B5%AC%ED%98%8..