리플렉션이란? 리플렉션은 자바의 기능 중 하나로, Runtime(실행 중)에 클래스의 정보를 동적으로 검사하고 조작할 수 있도록 한다. 리플렉션을 사용하면 클래스의 메서드, 필드, 생성자 등에 접근하고 호출할 수 있다. 리플렉션에 대해 이해하기 위해서는 JVM의 작동방식에 대해 이해할 필요가 있다. JVM은 클래스 로드시 Class Loader(클래스 로더)를 사용해 클래스에 대한 정보들을 저장한다. 이 때, 리플렉션에 사용되는 MetaData(메타데이터)를 Native Memory의 Metaspace(메타스페이스)에 저장한다. 리플렉션을 호출하는 시점에는 이미 해당 클래스의 로딩과 메타데이터 저장이 완료된 상태일 수 있다. 정리하자면 리플렉션은 로딩된 클래스의 메타데이터를 활용하여 클래스의 정보를 동적..
자바의 프로세스는 JVM에서 실행되는 독립적인 실행 프로그램이다. 자바 프로세스는 운영 체제에서 실행되기 위해 자원을 할당받고, 메모리 공간을 사용하며, 시스템 자원을 활용하여 작업을 수행한다. 자바 프로세스는 JVM을 통해 자바 언어로 작성된 소스 코드를 바이트 코드로 변화하고, 해당 바이트 코드를 실행해 프로그램을 동작시킨다. 이제부터 JVM에 대해 자세히 알아보겠다. 만약 JVM이 뭔지를 모른다면 아래의 게시글을 읽고 돌아오길 바란다. JVM & JRE & JDK 자바를 공부해본 사람이라면 자바는 플랫폼에 독립적이고, WORA("Write Once Run Anywhere" - 한 번 작성하면 모든 곳에서 돌릴 수 있다)는 말을 들어봤을 것이다. public class Main { public sta..
ConsumeEach() 그럼 명시적인 이터레이션을 사용하지 않고 채널에 있는 내용을 수신할 수는 없을까?? 이를 위한 메서드가 바로 consumeEach()이다. channel.consumeEach { println("Receiving Num $it") delay(100) } 위의 함수를 사용하면 송신측의 receive를 했을 때와 똑같은 결과를 얻을 수 있다. 또한 한 채널에서 생성한 데이터를 여러 개의 수신측이 가져갈 수도 있다. 이를 통해 데이터를 분류해서 처리할 수 있게 될 것이다. Produce() sequence() 함수와 비슷한 동시성 스트림을 생성할 수 있는 produce()라는 코루틴 빌더가 있다. 이 빌더는 ProducerScope 영역을 도입한다. fun main() { runBlo..
앱 아키텍처 가이드 | Android 개발자 | Android Developers 앱 아키텍처 가이드 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 이 가이드에는 고품질의 강력한 앱을 빌드하기 위한 권장사항 및 권장 아키텍처가 포함 developer.android.com 앱의 구성요소는 개별적이고 비순차적으로 실행될 수 있으며, 운영체제나 사용자가 언제든지 앱 구성요소를 제거할 수 있다. 이러한 이벤트는 직접 제어할 수 없기 때문에 앱 구성요소에 애플리케이션 데이터나 상태를 저장해서는 안 되며 구성요소가 서로 종속되면 안된다고 안드로이드는 말한다. ✔ 4가지의 일반 아키텍처 원칙 그래서 안드로이드의 앱은 견고성을 높이며 앱을 더 쉽게 테스트할 수 있도록 아키텍처를 정의하는..
RxJava에 대한 공부를 시작하는 이유 요즘 프로젝트를 진행하면서 Retrofit2를 이용해 서버와 통신을 많이 진행하고 있다. 네트워크 요청은 Call 객체를 통해 비동기적으로 수행되고, enqueue() 메서드를 호출해 비동기로 요청을 실행하거나 execute() 메서드를 호출하여 동기적으로 실행할 수 있다. 예시는 아래와 같다. interface MyApiService { @GET("users/{id}") fun getUser(@Path("id") userId: String): Call } val BASE_URL = "baseurl" val retrofit = Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFacto..
채널이란? 채널은 2개의 코루틴 사이를 연결할 수 있는 파이프 같은 것이다. 임의의 데이터 스트림을 코루틴 사이에 공유할 수 있다. 만약 채널 내부의 용량이 다 찼는데 데이터를 채널에 보내려고 하면, 채널은 현재 코루틴을 일시 중단시키고 나중에 재개하게 된다. 이 부분이 자바의 동시성 API에서의 Blocking Queue와 채널의 가장 큰 차이이다. 채널의 타입 채널의 타입은 크게 4가지로 나눌 수 있다. 1. Buffered 2. Rendezvous (Unbuffered) 3. Unlimited 4. Conflated 이제부터 이 4가지의 타입을 어떻게 사용하는지 알아보겠다. 1. Buffered 고정된 크기의 버퍼를 생성하는 타입이다. 아래의 예제를 보자 fun main() { runBlocking..
예외 처리의 경우, 코루틴 빌더들은 다음의 전략을 따른다 1. 부모 코루틴이 자식에게 발생한 오류와 동일한 오류로 취소된다. 2. 자식들이 모두 취소되면 부모는 예외를 코루틴 트리의 윗부분으로 전달한다. 아래의 코드를 보면서 이해해보자 코드 fun main() { runBlocking { launch { throw Exception("A에 에러 발생") println("A 완료") } launch { delay(1000) println("B 완료") } println("메인") } } 결과 메인 Exception in thread "main" java.lang.Exception: A에 에러 발생 위의 코드를 보게 되면 최상위 코루틴이 "A 완료" 를 시작하기 전에 예외가 발생한다. 이로 인해 최상위 코루..
잡은 동시성 작업의 생명주기를 표현하는 객체이다. 잡을 사용하면 작업 상태를 추적하고 필요할 때 그 작업을 취소할 수 있다. 잡의 객체에는 3개의 상태변수가 있다. isActive: 잡이 활성화 되었는지 isCancelled: 잡이 취소중이거나 취소 뒤었는지 isCompleted: 잡이 완료되거나 취소 되었는지 잡은 생성되자 마자 디폴트 상태인 활성화 상태가 된다. 잡을 생성할 때, CoroutineStart 타입의 파라미터를 지정해서 초기 상태를 지정할 수도 있다. CoroutineStart.DEFAULT: 디폴트 동작이며 잡을 즉시 시작한다. CoroutineStart.LAZY: 잡이 신규 상태가 되고 시작을 기다리게 된다. 다음의 예제를 보자 코드 fun main() { runBlocking { v..