자바 8 Lambda Java 8 이전 익명 클래스의 사용을 람다를 이용하여 더욱 간결하고 직관적으로 구현 가능 Stream 스트림 API를 통해 컬렉션을 처리하면서 발생하는 모호함과 반복적인 코드 문제와 멀티코어 활용 어려움이라는 두 가지 문제를 모두 해결 Optional LocalDateTime 기존 Date와 Calendar 클래스의 기능 부족과 비 표준적인 명명 규칙, 그리고 일관되지 못한 속성 값의 문제를 해결하기 위해 새로운 날짜 API가 추가 interface default Method PermGen Area 제거 Java8 이전에는 초기 설정 시 PermSize와 MaxPermSize를 설정해주어야 했으나, Java8부터는 Permanent Generation이 Metaspace로 대체되었..
Java
자바 API 로는 깊은 복사를 수행할 수 없다는 것을 알게 됐다. 따라서 외부 혹은 내부로부터 변경에 취약하지 않도록 내부 요소들이 불변 객체여야 한다. 방어적 복사는 생성자를 통해 초기화하거나 내부의 객체를 반환할 때, 새로운 객체로 감싸서 복사해주는 방법이다. 외부와 내부에서 주소 값을 공유하는 인스턴스의 관계를 끊어주기 위해서 방어적 복사를 사용한다. 또한, 외부로 값을 노출시킬 때도 관계를 끊어주기 위해서 복사본을 반환해준다. 1. 주소 복사 List copyNumbers = numbers; =의 경우 그저 참조변수를 하나 만들어 주소를 넣어주기 때문에 완전히 동일한 컬렉션이다. 2. = new ArrayList() List newNubmers = new ArrayList(numbers); 방어적..
불변 객체(Immutable Object) 및 final을 사용해야 하는 이유 객체 생성 이후 내부 상태가 변하지 않는, 변경할 수 없는 객체를 이야기합니다. 불변객체는 내부 상태를 변경하는 메소드를 제공하지 않거나 방어적 복사를 통해 데이터를 제공합니다. 대표적으로 Java의 String, Integer, Long, Double 등등 있습니다. 1. Thread-Safe하여 병렬 프로그래밍에 유용하며, 동기화를 고려하지 않아도 된다. 멀티 쓰레드 환경에서 동기화 문제가 발생하는 이유는 공유 자원에 동시에 쓰기(Write) 때문이다. 하지만 만약 공유 자원이 불변이라면 더 이상 동기화를 고려하지 않아도 될 것이다. 왜냐하면 항상 동일한 값을 반환할 것이기 때문이다. 이는 안정성을 보장할 뿐만 아니라 동기..
String String 클래스는 불변 객체이다. 따라서 한 번 할당한 문자열을 변경하는 것은 불가능하며, 더하기 연산을 하여 문자를 이어 붙일 때는 새로운 객체가 생성되어 재할당된다. 반복적으로 문자열을 이어 붙이다 보면 Heap 영역에서 참조를 잃은 문자열 객체가 계속해서 쌓이게 된다. 물론, 나중에 GC에 의해 수거가 되지만 메모리 관리 측면에서 이러한 코드는 결코 좋은 코드라고 할 수 없다. 또한 계속해서 객체를 생성하므로 연산 속도 측면에서도 성능이 떨어질 수 밖에 없다. String 객체 생성 new 연산자로 String 객체를 생성하면 JVM 에서 Heap 영역에서 String 객체 생성. new 연산자가 아닌 리터럴("")로 String 객체를 생성하면 JVM 은 우선 String Cons..
equals 메소드 equals 메소드는 기본적으로 2개의 객체가 동일한지 검사하기 위해 사용. 2개의 객체가 참조하는 것이 동일한지를 확인하는 것이며, 이는 동일성(Identity)을 비교하는 것. 동일한 메모리 주소일 경우에만 동일한 객체가 된다. 하지만 프로그래밍을 하다보면 동일한 객체가 메모리 상에 여러 개 띄워져있는 경우가 있다. 해당 객체는 서로 다른 메모리에 띄워져있으므로 동일한(Identity) 객체가 아니다. 하지만 프로그래밍 상으로는 같은 값을 지니므로 같은 객체로 인식되어야 하는데, 이러한 동등성(Equality)를 위해 우리는 값으로 객체를 비교하도록 equals 메소드를 오버라이딩해주는 것이다. hashCode 메소드 hashCode 메서드는 객체의 주소 값을 이용해서 해싱(has..
Stream 함수형 인터페이스(람다식)을 적용하여 컬렉션과 같은 저장요소를 반복적으로 처리할 수 있는 기능 1. Immutable 스트림은 원본 객체의 값을 사용하기만 할 뿐 변경하지 않는다. 스트림은 최종 처리를 통해 원본과 무관한 새로운 객체를 생성한다. 2. 일회용 스트림은 생성되고, 중간처리를 거쳐 최종처리까지 완료되면 닫히게 된다. 이미 닫힌 스트림은 재사용할 수 없으며, 재사용을 시도할 경우 예외가 발생한다. 3. 생성, 중간처리, 최종처리 스트림의 처리는 생성, 중간처리, 최종처리 3단계로 구분된다. 4. 지연 연산 간단히 말해 결과값이 필요할 때까지 계산을 늦추는 기법이다. 스트림 파이프라인을 실행하게 되면 JVM은 곧바로 스트림 연산을 실행시키지 않고, 스트림 파이프라인이 어떠한 중간연산..
람다 표현식 람다 표현식(lambda expression)이란 함수형 프로그래밍을 구성하기 위한 함수식이며, 간단히 말해 자바의 메소드를 간결한 함수식으로 표현한 것이다. 지금까지 자바에서는 메서드를 하나 표현하려면 클래스를 정의해야 했다. 하지만 람다식으로 표현하면 메서드의 이름과 반환값을 생략할 수 있고 이를 변수에 넣어 자바 코드가 매우 간결해지는 장점이 있다. 아래 그림에서 보듯이 int add(int a, int b) {} 메소드 표현식을, 메서드 타입, 메서드 이름, 매개변수 타입, 중괄호, return 문을 생략하고, 화살표 기호를 넣음으로써 코드를 혁명적으로 함축했음을 볼 수 있다. 이러한 특징으로 람다식을 이름이 없는 함수 익명 함수(anonymous function) 라고도 한다. 사실..
자바에는 Call by Reference 개념이 없다 C언어는 포인터를 통해 그대로 주소를 통해 메모리를 참조할 수 있지만, 자바에서는 포인터를 철저하게 숨겨 개발자가 직접 메모리 주소에 접근하지 못하게 조치했다. 자바에서의 파라미터는 call by value로서만 동작되며, 원시값이 복사되느냐 주소값이 복사되느냐 차이가 있을 뿐이다. 매개변수에 복사된 값에 따라, 원시값이면 바로 연산을 하고 주소값이면 해당 메모리 주소를 참조해 값을 가져와 연산할 뿐이다. Call by Value 과정 1. main 스택 프레임에 두 변수가 담기게 된다. primitive 타입인 변수 var은 그대로 원시값 1을 지니게되며, reference 타입인 배열 변수 arr은 실제 데이터 heap 영역에 저장되게 되고 이를 ..
인터페이스 vs 추상클래스 사용처 인터페이스나 추상클래스나 둘이 똑같이 추상 메소드를 통해 상속/구현을 통한 메소드 강제 구현 규칙을 가지는 추상화 클래스이다. 추상클래스를 사용하는 경우 상속 받을 클래스들이 공통으로 가지는 메소드와 필드가 많아 중복 멤버 통합을 할 때 공통된 기능 구현이 필요하거나, 공통으로 지켜야 할 규칙도 있을때 상속을 통해 구조화 하여 재정의(overriding)을 통해 구현한다. 추상클래스는 '클래스로서' 클래스와 의미있는 연관 관계를 구축할때 사용된다 인터페이스를 사용하는 경우 인터페이스의 가장 큰 특징은 상속에 구애 받지 않은 상속(구현) 가 가능하다는 것이다. 따라서 상속에 얽매히지 않는 인터페이스에 추상 메소드를 선언하고 이를 구현(implements) 하면서 자유로운 ..
객체 지향 설계의 5원칙 S.O.L.I.D 좋은 설계란 시스템에 새로운 요구사항이나 변경사항이 있을 때, 영향을 받는 범위가 적은 구조를 말한다. 그래서 시스템에 예상하지 못한 변경사항이 발생하더라도, 유연하게 대처하고 이후에 확장성이 있는 시스템 구조를 만들 수 있다. 즉, SOLID 객체 지향 원칙을 적용하면 코드를 확장하고 유지 보수 관리하기가 더 쉬워지며, 불필요한 복잡성을 제거해 리팩토링에 소요되는 시간을 줄임으로써 프로젝트 개발의 생산성을 높일 수 있다. 1. 단일 책임 원칙 - SRP (Single Responsibility Principle) 단일 책임 원칙은 클래스(객체)는 단 하나의 책임만 가져야 한다는 원칙 즉, 하나의 클래스는 하나의 기능 담당하여 하나의 책임을 수행하는데 집중되도록..