Dev/JAVA 63

[JAVA] String, StringBuffer, StringBuilder의 차이

String, StringBuffer, StringBuilder의 차이를 정리하면 아래와 같다. String은 불변객체이고 StringBuffer, StringBuilder는 가변객체이다. StringBuffer는 멀티스레드 환경에서 사용되고 StringBuilder는 싱글스레드 환경에서 사용된다. 왜 이런 차이를 보이는 것일까? String이 불변객체인 이유 String이 불변객체인 이유는 JAVA가 문자열 리터럴을 String Constant Pool로 관리하기 때문이다. "안녕하세요", "반갑습니다.", "hello" 처럼 선언된 문자열은 문자열 리터럴로 간주되어 Heap 메모리 안에 생성된 String Constant Pool에 문자열 객체로 등록된다. 스레드A가 "안녕하세요" 문자열 객체를 리터..

Dev/JAVA 2024.02.23

[JAVA] Garbage Collector 동작원리

JAVA와 C, C++의 가장 큰 차이 중 하나는 가비지 컬렉터(Garbage Collector) 이다. JVM의 스레드는 Stack 영역에 독립된 공간을 가지고 Heap 영역은 공유한다. 그래서 가비지 컬렉터 스레드가 Heap 영역의 생성된 객체에 접근하여 제거할 수 있다. 이런 구조는 C/C++도 마찬가지이지만, C/C++은 가비지 컬렉터를 가지고 있지 않다. 왜냐하면 가비지 컬렉터는 치명적인 단점을 가지고 있기 때문이다. 가비지 컬렉터는 Mark-Sweep-Compaction 과정을 거쳐 객체를 제거한다. Mark 전역 메모리 영역, 스택 영역의 참조변수에서 접근할 수 있는 객체는 reachable, 접근할 수 없는 객체는 unreachable로 표시(Mark)한다. Sweep unreachable..

Dev/JAVA 2024.02.23

[JAVA] JDK 동작원리

JDK( Java Develoment Kit ) JDK는 자바 컴파일 도구(javac) , 자바 실행 환경 ( JRE ) , 자바 실행 머신 ( JVM )이 합쳐진 도구이다. JAVA 언어로 개발하려면 JDK가 필요하지만 단순히 실행만 한다면 JRE만 있어도 된다. 그럼 이제 JDK는 어떻게 동작하는지 구체적으로 알아보자. 객체지향언어, JAVA C,C++은 절차지향언어지만 JAVA는 객체지향언어이다. 절차지향언어는 코드의 '순서'가 중요하므로 코드 전체가 유기적으로 연결되어 있다. 그래서 메모리에 올라갔을 때의 주소도 논리적으로 이미 정해져 있다. 이를 '정적바인딩'이라 부른다. C,C++은 컴파일(compile)을 하면 컴퓨터가 이해할 수 있는 언어인 어셈블리어로 바로 변환된다. 이미 메모리 위치까지..

Dev/JAVA 2024.02.22

[Modern JAVA] 클로저(Closure)란?

JAVA에서 클로저(Closure)란? 클로저(Closure)란, 외부 스코프에 선언된 변수를 다른 스코프 영역에서 참조하는 기술이다. 사실, JAVA에서 클로저는 없는 개념이다. 익명함수 클래스나 람다로 인스턴스를 생성할 때, 외부 스코프 변수를 캡처하여 인스턴스 내부에 저장하는 '캡처링' 기술을 두고, 단순히 클로저라 부르는 것이다. 외부에 선언된 변수를 내부에서 사용하니, 마치 클로저 같은 기능을 하기에 붙여진 이름이다. 외부 변수를 캡처하여 인스턴스에 저장하면, 외부에 있는 데이터와 인스턴스에 저장된 데이터는 서로 동일해야 한다. 만약 둘 중 하나가 변경되면 데이터 멱등성이 훼손되기 때문이다. 그래서 JAVA8 이전에는 캡처링 기술이 적용될 변수는 변경되지 못하도록 final 선언을 강제했다. J..

Dev/JAVA 2024.01.31

[MODERN JAVA] 람다 깔끔하게 사용하기 ( 메서드 참조 )

람다는 메서드 참조로 깔끔하게 표현될 수 있다. 리스트를 정렬하는 코드를 람다로 표현하면 아래와 같다. 람다표현식 List str = Arrays.asList("a","b","A","B"); str.sort((s1,s2)-> s1.compareToIgnoreCase(s2)); List 인터페이스의 sort 메소드는 Comparator 함수형 인터페이스를 인수로 갖는다. 그럼 람다는 Compartor의 유일한 메서드인 compare()를 람다표현식으로 표현해야 한다. (s1,s2)-> s1.compareToIgnoreCase(s2) 컴파일러는 함수형인터페이스의 함수디스크립터와 람다표현식이 호환되는지 검사한다. 메서드 참조 List str = Arrays.asList("a","b","A","B"); str...

Dev/JAVA 2023.06.30

[MODERN JAVA] 람다 캡처링 ( Lambda Capturing )

람다 캡처링( Lambda Capturing )을 알아보기 전에, 간단히 JVM의 메모리 구성을 알아보자. JVM은 STACK, HEAP, METHOD 영역으로 메모리 영역이 나뉜다. HEAP 영역은 동적으로 생성된 객체가 저장된다. STACK 영역은 실행된 스레드가 스택 구조로 쌓인다. 이때 스레드는 Heap 영역의 객체에 접근하여 메소드 영역에 저장된 메소드를 실행하는데, 실행된 메소드는 '프레임' 단위로 다시 STACK 영역에 쌓인다. 그럼 위 개념을 숙지하고 람다 캡처링에 대해서 하나씩 알아보자. 이해하기 쉽도록 예를 들어보겠다. 농부가 있다. 농부는 과수원을 운영하는데, 수확한 사과 중 상품성있는 사과를 분류하려고 한다. 농부는 사과분류머신을 사용하였고 사과분류머신은 '무게'로 상품성있는 사과를..

Dev/JAVA 2023.06.02

[MODERN JAVA] 컴파일러가 보는 람다(Lambda)

람다는 파라미터로 코드를 넘기는 기술이다. 사과를 분류하는 메소드가 있다. 메소드는 사과를 분류하는 로직을 갖는데, 로직은 정부정책에 따라 매번 바뀐다고 가정하자. 매번 바뀌는 로직 때문에 메소드를 매번 수정하기는 번거로우니 분류 로직만 변경하고 싶다. 이때, 로직을 간편하게 넘길 수 있는 기술이 '람다'이다. 파라미터로 '로직'만 넘겨받으면 메소드는 어떤 수정도 할 필요가 없다. 정책에 따라 파라미터로 넘겨받는 로직만 달리하면 되기 때문이다. 그러나 파라미터도 일종의 '변수'로 원시타입이나 참조타입만 들어갈 수 있다. '코드'가 들어갈 수 없다. 그래서 JAVA는 함수형 인터페이스를 사용한다. 함수형 인터페이스란, 메소드가 하나밖에 없는 인터페이스이다. 하나밖에 없는 메소드는 '함수'이다. 람다는 함수..

Dev/JAVA 2023.06.01

[JAVA] 어노테이션( Annotation )의 속성

[JAVA] 어노테이션( Annotation )이란? (1) 어노테이션(Annotation)은 무엇일까? 어노테이션은 '주석'이다. JVM이 읽는 주석이다. 주석이 필요한 이유가 무엇일까? 철학책과 과학책이 있다. 과학책은 과학코너로 철학책은 철학코너로 분류하고 lordofkangs.tistory.com 이전 포스팅에서 어노테이션의 개념을 알아보았다. 이번 포스팅에서는 어노테이션의 속성을 다루어보겟다. 어노테이션의 속성 어노테이션은 '특정한 로직'이 처리되어야 하는 대상에 남기는 '표시'이다. '표시'를 남길 때, 단순히 '@' 하나로만 남기면 구체적인 정보를 제공할 수 없다. 조금 더 세밀한 작업을 위해서는 구체적인 데이터를 담아야 하는데, 어노테이션의 속성이 그 역할을 한다. 속성은 추상메소드로 구현..

Dev/JAVA 2023.05.29

[JAVA] 어노테이션( Annotation )이란?

어노테이션(Annotation)은 무엇일까? 어노테이션은 '주석'이다. JVM이 읽는 주석이다. 주석이 필요한 이유가 무엇일까? 철학책과 과학책이 있다. 과학책은 과학코너로 철학책은 철학코너로 분류하고 싶다. 그런데 철학책과 과학책은 외관으로 구분하기 어렵다. 그래서 색상 인식 분류기를 하나 구매했다. 색상인식분류기가 구분할 수 있도록 과학책 오른쪽 상단에 '파란원' 표시를 남겼다. 파란원이 있는 책은 과학코너로 분류되어야 한다. 어노테이션은 '파란원'과 같다. 클래스는 모두 구조가 같다. 모두 필드와 메소드로 구성되어 있다. 외관으로는 구분이 안되나 클래스의 목적은 제각기 다르다. 그래서 개발자는 처리를 달리하고 싶은 대상에 어노테이션을 표시해 JVM에게 알려준다. @Entity @Entity publ..

Dev/JAVA 2023.05.29

[MODERN JAVA] 람다(Lambda)의 활용 - Predicate, Consumer, Function

[MODERN JAVA] 람다(Lambda)의 활용 - 실행 어라운드 패턴 [MODERN JAVA] 람다(Lambda)란? 파라미터로 값이 아닌 '코드'를 넘겨야 하는 순간이 있다. 이때 사용하는 기술이 '동적 파라미터화'이다. '람다'가 등장하기 전에는 동적 파라미터화는 무겁게 구현되었 lordofkangs.tistory.com 지난 포스팅에서는 람다가 사용되는 패턴을 알아보았다. 이번 포스팅에서는 자바API의 함수형 인터페이스 몇 가지를 알아보겠다. 함수형 인터페이스는 동적파라미터를 구현하기 위한 그릇이다. 동적 파라미터란, 파라미터 인수로 '코드(Code)'를 넘기는 기술로 일회적이거나 로직이 계속 변경되는 경우에 사용된다. Predicate Predicate는 참,거짓을 Return하는 함수형 인..

Dev/JAVA 2023.03.15