The Java

λ°±κΈ°μ„ λ‹˜μ˜ 더 μžλ°”, Java 8arrow-up-right, 더 μžλ°”, μ½”λ“œλ₯Ό μ‘°μž‘ν•˜λŠ” λ‹€μ–‘ν•œ 방법arrow-up-right κ°•μ˜λ₯Ό μš”μ•½ν•œ λ‚΄μš©μž…λ‹ˆλ‹€.

Java 8

Java 8

.

LTS(Long-Term-Support)

  • λΉ„-LTS

    • 배포 μ£ΌκΈ°: 6κ°œμ›”

    • 지원 κΈ°κ°„: 배포 이후 6κ°œμ›”(λ‹€μŒ 버전이 λ‚˜μ˜€λ©΄ 지원 μ’…λ£Œ)

  • LTS

    • 배포 μ£ΌκΈ°: 3λ…„(λ§€ 6번째 배포판이 LTS)

    • 지원 κΈ°κ°„: 5년이상(JDK 제곡 밴더와 μ΄μš©ν•˜λŠ” μ„œλΉ„μŠ€μ— 따라 차이)

    • μ‹€μ œ μ„œλΉ„μŠ€ 운영 ν™˜κ²½μ—μ„œλŠ” LTS 버전 ꢌμž₯

  • λ§€λ…„ 3μ›”κ³Ό 9월에 μƒˆ 버전 배포

Functional Interface & Lambda

ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€(Functional Interface)

  • 좔상 λ©”μ†Œλ“œλ₯Ό λ”± ν•˜λ‚˜λ§Œ κ°€μ§€κ³  μžˆλŠ” μΈν„°νŽ˜μ΄μŠ€

  • SAM(Single Abstract Method) μΈν„°νŽ˜μ΄μŠ€

  • @FuncationInterface μ• λ…Έν…Œμ΄μ…˜μ„ κ°€μ§€κ³  μžˆλŠ” μΈν„°νŽ˜μ΄μŠ€

.

λžŒλ‹€ ν‘œν˜„μ‹(Lambda Expressions)

  • κ°„κ²°ν•œ μ½”λ“œ

  • ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“œλŠ” λ°©λ²•μœΌλ‘œ μ‚¬μš© κ°€λŠ₯

  • λ©”μ†Œλ“œ λ§€κ°œλ³€μˆ˜, 리턴 νƒ€μž…, λ³€μˆ˜λ‘œ λ§Œλ“€μ–΄ μ‚¬μš© κ°€λŠ₯

.

μžλ°”μ—μ„œ ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°

  • ν•¨μˆ˜λ₯Ό First class object둜 μ‚¬μš© κ°€λŠ₯

  • 순수 ν•¨μˆ˜(Pure function)

    • μ‚¬μ΄λ“œ 이팩트 μ—†μŒ(ν•¨μˆ˜ 밖에 μžˆλŠ” 값을 λ³€κ²½ν•˜μ§€ μ•ŠμŒ)

    • μƒνƒœκ°€ μ—†μŒ(ν•¨μˆ˜ 밖에 μžˆλŠ” 값을 μ‚¬μš©ν•˜μ§€ μ•ŠμŒ)

  • κ³ μ°¨ ν•¨μˆ˜(Higher-Order Function)

    • ν•¨μˆ˜κ°€ ν•¨μˆ˜λ₯Ό λ§€κ°œλ³€μˆ˜λ‘œ 받을 수 있고, ν•¨μˆ˜ 리턴 κ°€λŠ₯

  • λΆˆλ³€μ„±

Functional Interface

Java κΈ°λ³Έ 제곡 ν•¨μˆ˜ν˜• μΈν„°νŽ˜μ΄μŠ€

Function<T, R>

  • T νƒ€μž…μ„ λ°›μ•„μ„œ R νƒ€μž…μ„ λ¦¬ν„΄ν•˜λŠ” ν•¨μˆ˜ μΈν„°νŽ˜μ΄μŠ€

BiFunction<T, U, R>

  • 두 개의 κ°’(T, U)λ₯Ό λ°›μ•„μ„œ R νƒ€μž…μ„ λ¦¬ν„΄ν•˜λŠ” ν•¨μˆ˜ μΈν„°νŽ˜μ΄μŠ€

  • R apply(T t, U u)

Consumer<T>

  • T νƒ€μž…μ„ λ°›μ•„μ„œ 아무값도 λ¦¬ν„΄ν•˜μ§€ μ•ŠλŠ” ν•¨μˆ˜ μΈν„°νŽ˜μ΄μŠ€

Supplier<T>

  • T νƒ€μž…μ˜ 값을 μ œκ³΅ν•˜λŠ” ν•¨μˆ˜ μΈν„°νŽ˜μ΄μŠ€

Predicate<T>

  • T νƒ€μž…μ„ λ°›μ•„μ„œ boolean을 λ¦¬ν„΄ν•˜λŠ” ν•¨μˆ˜ μΈν„°νŽ˜μ΄μŠ€

  • ν•¨μˆ˜ μ‘°ν•©μš© λ©”μ†Œλ“œ

UnaryOperator<T>

  • Function<T, R>의 νŠΉμˆ˜ν•œ ν˜•νƒœ(Function 상속)

  • μž…λ ₯κ°’ ν•˜λ‚˜λ₯Ό λ°›μ•„μ„œ λ™μΌν•œ νƒ€μž…μ„ λ¦¬ν„΄ν•˜λŠ” ν•¨μˆ˜ μΈν„°νŽ˜μ΄μŠ€

BinaryOperator<T>

  • BiFunction<T, U, R>의 νŠΉμˆ˜ν•œ ν˜•νƒœ

  • λ™μΌν•œ νƒ€μž…μ˜ μž…λ ΅κ°’ 두 개λ₯Ό λ°›μ•„ λ¦¬ν„΄ν•˜λŠ” ν•¨μˆ˜ μΈν„°νŽ˜μ΄μŠ€

Lambda

Lambda Expressionsarrow-up-right

(인자 리슀트) -> {λ°”λ””}

.

인자 리슀트

  • 인자 μ—†μŒ: ()

  • μΈμžκ°€ ν•œ 개: (one) λ˜λŠ” one

  • μΈμžκ°€ μ—¬λŸ¬ 개: (one, two)

  • 인자의 νƒ€μž…μ€ μƒλž΅ κ°€λŠ₯(μ»΄νŒŒμΌλŸ¬κ°€ μΆ”λ‘ ν•˜μ§€λ§Œ λͺ…μ‹œλ„ κ°€λŠ₯)

.

λ°”λ””

  • ν™”μ‚΄ν‘œ 였λ₯Έμͺ½μ— ν•¨μˆ˜ λ³Έλ¬Έ μ •μ˜

  • μ—¬λŸ¬ 쀄인 경우 {} μ‚¬μš©

  • ν•œ 쀄인 경우 λ°”λ””, return μƒλž΅ κ°€λŠ₯

.

λ³€μˆ˜ 캑처(Variable Capture)

  • 둜컬 λ³€μˆ˜ 캑처

    • final, effective final 인 κ²½μš°μ—λ§Œ μ°Έμ‘° κ°€λŠ₯

    • κ·Έλ ‡μ§€ μ•Šμ„ 경우, concurrency λ¬Έμ œκ°€ λ°œμƒν•  수 μžˆμ–΄μ„œ μ»΄νŒŒμΌλŸ¬κ°€ λ°©μ§€

  • effective final

    • μžλ°” 8λΆ€ν„° μ§€μ›ν•˜λŠ” κΈ°λŠ₯

    • final ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šμ§€λ§Œ, 변경이 μ—†λŠ” λ³€μˆ˜λ₯Ό 읡λͺ… 클래슀 κ΅¬ν˜„μ²΄, λžŒλ‹€μ—μ„œ μ°Έμ‘° κ°€λŠ₯

  • λžŒλ‹€λŠ” 읡λͺ… 클래슀 κ΅¬ν˜„μ²΄μ™€ 달리 Shadowingarrow-up-rightν•˜μ§€ μ•ŠμŒ

    • 읡λͺ… ν΄λž˜μŠ€λŠ” μƒˆλ‘œμš΄ 슀μ½₯을 λ§Œλ“€μ§€λ§Œ, λžŒλ‹€λŠ” λžŒλ‹€λ₯Ό 감싸고 μžˆλŠ” 슀μ½₯κ³Ό κ°™μŒ

    • λžŒλ‹€λ₯Ό 감싼 슀μ½₯에 μžˆλŠ” λ™μΌν•œ μ΄λ¦„μ˜ λ³€μˆ˜ μ •μ˜ λΆˆκ°€

Method Reference

Method Referencesarrow-up-right λ₯Ό μ‚¬μš©ν•΄μ„œ λ©”μ†Œλ“œ, μƒμ„±μž 호좜λ₯Ό 맀우 κ°„κ²°ν•˜κ²Œ ν‘œν˜„ κ°€λŠ₯

Interface

Default Methodsarrow-up-right

Collection interface

  • μΈν„°νŽ˜μ΄μŠ€μ— λ©”μ†Œλ“œ 선언이 μ•„λ‹ˆλΌ κ΅¬ν˜„μ²΄λ₯Ό μ œκ³΅ν•˜λŠ” 방법

  • κ΅¬ν˜„ 클래슀λ₯Ό κΉ¨λœ¨λ¦¬μ§€ μ•Šκ³  μƒˆ κΈ°λŠ₯ μΆ”κ°€ κ°€λŠ₯

  • Default Methods λŠ” κ΅¬ν˜„μ²΄ λͺ¨λ₯΄κ²Œ μΆ”κ°€λœ κΈ°λŠ₯으둜 리슀크 쑴재

    • 컴파일 μ—λŸ¬λŠ” μ•„λ‹ˆμ§€λ§Œ κ΅¬ν˜„μ²΄μ— 따라 λŸ°νƒ€μž„ μ—λŸ¬(ex. NPE) λ°œμƒ κ°€λŠ₯

    • λ°˜λ“œμ‹œ λ¬Έμ„œν™” ν•„μš”(@implSpec μ‚¬μš©)

    • ν•„μš” μ‹œ κ΅¬ν˜„μ²΄κ°€ μž¬μ •μ˜

  • Object κ°€ μ œκ³΅ν•˜λŠ” κΈ°λŠ₯(equals, hasCode)은 κΈ°λ³Έ λ©”μ†Œλ“œλ‘œ 제곡 λΆˆκ°€

    • κ΅¬ν˜„μ²΄κ°€ μž¬μ •μ˜

  • 본인이 μˆ˜μ •ν•  수 μžˆλŠ” μΈν„°νŽ˜μ΄μŠ€μ—λ§Œ κΈ°λ³Έ λ©”μ†Œλ“œ 제곡 κ°€λŠ₯

  • μΈν„°νŽ˜μ΄μŠ€λ₯Ό μƒμ†λ°›λŠ” μΈν„°νŽ˜μ΄μŠ€μ—μ„œ κΈ°λ³Έ λ©”μ†Œλ“œλ₯Ό λ‹€μ‹œ 좔상 λ©”μ†Œλ“œλ‘œ λ³€κ²½ κ°€λŠ₯

  • κΈ°λ³Έ λ©”μ†Œλ“œκ°€ μΆ©λ™ν•˜λŠ” 경우 직접 μ˜€λ²„λΌμ΄λ”© ν•„μš”

.

Static Method

  • ν•΄λ‹Ή νƒ€μž… κ΄€λ ¨ 헬퍼, μœ ν‹Έλ¦¬ν‹° λ©”μ†Œλ“œ 제곡 μ‹œ 유용

.

Java 8 Default Methods

Iterablearrow-up-right κΈ°λ³Έ λ©”μ†Œλ“œ

Collectionarrow-up-right κΈ°λ³Έ λ©”μ†Œλ“œ

  • parallelStream(), spliterator()

Comparatorarrow-up-right κΈ°λ³Έ λ©”μ†Œλ“œ 및 μŠ€νƒœν‹± λ©”μ†Œλ“œ

  • thenComparing()

  • static reverseOrder() / naturalOrder()

  • static nullsFirst() / nullsLast()

  • static comparing()

Spliteratorarrow-up-right κΈ°λ³Έ λ©”μ†Œλ“œ

  • forEachRemaining(Consumer)

  • getExactSizeIfKnown()

  • hasCharacteristics()

  • getComparator()

Stream

Package java.util.streamarrow-up-right

Streamarrow-up-right

  • 데이터λ₯Ό λ‹΄κ³  μžˆλŠ” μ €μž₯μ†Œ(μ»¬λ ‰μ…˜)κ°€ μ•„λ‹ˆλΌ, μ–΄λ– ν•œ μ—°μ†λœ 데이터λ₯Ό μ²˜λ¦¬ν•˜λŠ” μ˜€νΌλ ˆμ΄μ…˜λ“€μ˜ λͺ¨μŒ

  • 슀트림 처리 μ‹œ 데이터 원본은 λ³€κ²½ν•˜μ§€ μ•ŠμŒ

  • 슀트림으둜 μ²˜λ¦¬ν•˜λŠ” λ°μ΄ν„°λŠ” 였직 ν•œ 번만 처리

  • μ‹€μ‹œκ°„μœΌλ‘œ 슀트림 데이터가 λ“€μ–΄μ˜¬ 경우 λ¬΄ν•œ 처리(Short Circuit λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•΄μ„œ μ œν•œ κ°€λŠ₯)

  • μ€‘κ°œ μ˜€νΌλ ˆμ΄μ…˜μ€ 근본적으둜 lazy νŠΉμ„±μ„ 가짐

  • 데이터가 λ°©λŒ€ν•œ 경우 parallelStream() 으둜 μ†μ‰½κ²Œ 병렬 처리 κ°€λŠ₯

    • μŠ€λ ˆλ“œ 생성, λ³‘λ ¬μ²˜λ¦¬ ν›„ μˆ˜μ§‘, μŠ€λ ˆλ“œ κ°„ μ»¨ν…μŠ€νŠΈ μŠ€μœ„μΉ­ λ“±μ˜ λΉ„μš©μœΌλ‘œ 무쑰건 λΉ¨λΌμ§€λŠ” 건 μ•„λ‹˜

슀트림 νŒŒμ΄ν”„λΌμΈ

  • 0 λ˜λŠ” λ‹€μˆ˜μ˜ μ€‘κ°œ μ˜€νΌλ ˆμ΄μ…˜κ³Ό ν•œ 개의 μ’…λ£Œ μ˜€νΌλ ˆμ΄μ…˜μœΌλ‘œ ꡬ성

  • 슀트림의 데이터 μ†ŒμŠ€λŠ” 였직 터미널 μ˜€νΌλ„€μ΄μ…˜μ„ μ‹€ν–‰ν•  λ•Œμ—λ§Œ 처리

μ€‘κ°œ μ˜€νΌλ ˆμ΄μ…˜(intermediate operation)

  • Stream 리턴

  • Stateless / Stateful μ˜€νΌλ ˆμ΄μ…˜μœΌλ‘œ 더 μƒμ„Έν•˜κ²Œ ꡬ뢄 κ°€λŠ₯

    • λŒ€λΆ€λΆ„ Stateless operation

    • 이전 μ†ŒμŠ€ 데이터λ₯Ό μ°Έμ‘°ν•΄μ•Ό ν•˜λŠ” μ˜€νΌλ ˆμ΄μ…˜(ex. distinct, sorted)은 Stateful μ˜€νΌλ ˆμ΄μ…˜

  • filter, map, limit, skip, sorted ...

μ’…λ£Œ μ˜€νΌλ ˆμ΄μ…˜(terminal operation)

  • Stream 리턴 X

  • collect, allMatch, count, forEach, min, max ...

.

Stream API

StreamTestarrow-up-right

필터링

슀트림 λ³€κ²½

슀트림 생성과 μ œν•œ

μŠ€νŠΈλ¦Όμ— μžˆλŠ” 데이터가 νŠΉμ • 쑰건을 λ§Œμ‘±ν•˜λŠ”μ§€ 확인

μŠ€νŠΈλ¦Όμ„ 데이터 ν•˜λ‚˜λ‘œ λ­‰μΉ˜κΈ°

  • reduce(identity, BiFunction), collect(), sum(), max()

Optional

Class Optionalarrow-up-right

NullPointerException 을 λ§Œλ‚˜λŠ” 이유

  • null 을 λ¦¬ν„΄ν•˜κ³ , null 체크λ₯Ό λ†“μΉ˜κΈ° λ–„λ¬Έ

λ©”μ†Œλ“œμ—μ„œ μž‘μ—… 쀑 νŠΉλ³„ν•œ μƒν™©μ—μ„œ 값을 μ œλŒ€λ‘œ 리턴할 수 μ—†λŠ” 경우 선택할 수 μžˆλŠ” 방법

  • μ˜ˆμ™Έ λ˜μ§„κΈ° (μŠ€νƒνŠΈλ ˆμ΄μŠ€λ₯Ό μ°μ–΄λ‹€λ³΄λ‹ˆ λΉ„μ‹Ό λΉ„μš© λ°œμƒ)

  • null 리턴 (ν΄λΌμ΄μ–ΈνŠΈμͺ½μ—μ„œ null 처리 ν•„μš”)

  • Optional 리턴 (ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ λͺ…μ‹œμ μœΌλ‘œ 빈 값일 μˆ˜λ„ μžˆλ‹€λŠ” 것을 μ „λ‹¬ν•˜κ³ , 빈 값인 κ²½μš°μ— λŒ€ν•œ 처리λ₯Ό κ°•μ œ)

Optional

  • ν•œ 개의 값이 λ“€μ–΄μžˆμ„ μˆ˜λ„ 없을 μˆ˜λ„ μžˆλŠ” μ»¨λ„€μ΄λ„ˆ

주의점

  • λ¦¬ν„΄κ°’μœΌλ‘œλ§Œ μ‚¬μš© ꢌμž₯

    • λ©”μ†Œλ“œ λ§€κ°œλ³€μˆ˜ νƒ€μž…μœΌλ‘œ μ‚¬μš© μ‹œ, 번거둭게 null + optional 체크 ν•„μš”

    • 맡의 ν‚€ νƒ€μž…μœΌλ‘œ μ‚¬μš© μ‹œ, 맡의 ν‚€κ°€ 없을 μˆ˜λ„ μžˆλ‹€λŠ” μœ„ν—˜ 제곡

    • μΈμŠ€ν„΄μŠ€ ν•„λ“œ νƒ€μž…μœΌλ‘œ μ‚¬μš© μ‹œ, ν•„λ“œκ°€ 없을 μˆ˜λ„ μžˆλ‹€λŠ” μœ„ν—˜ 제곡

  • null λŒ€μ‹  Optional.empty() 리턴 ꢌμž₯

  • Primitive Type Optional 제곡

    • λ°•μ‹±, μ–Έλ°•μ‹± λ°œμƒμ„ λ°©μ§€ν•˜κ³ , μ„±λŠ₯ ν–₯상을 μœ„ν•΄ μ‚¬μš© ꢌμž₯

    • OptionalInt, OptionalLong ...

  • Collection, Map, Stream Array, Optional은 Opiontal 둜 두 번 감싸지 μ•ŠκΈ°

Tired of Null Pointer Exceptions? Consider Using Java SE 8's "Optional"!arrow-up-right

.

Optional API

OptionalTestarrow-up-right

Optional 생성

Optional κ°’ 포함 μ—¬λΆ€ 확인

Optional κ°’ κ°€μ Έμ˜€κΈ°

Optional 에 값이 μ‘΄μž¬ν•  경우 λ™μž‘ μˆ˜ν–‰

Optional 에 값이 μžˆμ„ 경우 κΊΌλ‚΄κ³ , 무쑰건 μƒˆλ‘œμš΄ 클래슀 생성

Optional 에 값이 μžˆμ„ 경우 κΊΌλ‚΄κ³ , μ—†μœΌλ©΄ μƒˆλ‘œμš΄ 클래슀 제곡

Optional 에 값이 μžˆμ„ 경우 κΊΌλ‚΄κ³ , μ—†μœΌλ©΄ μ˜ˆμ™Έ

Optional 값을 필터링

Optional 값을 λ§€ν•‘(λ³€ν™˜)

  • flatMap(Function): Optional μ•ˆμ— λ“€μ–΄μžˆλŠ” μΈμŠ€ν„΄μŠ€κ°€ Optional 인 경우 편리

Date & Time API

java 8 에 μƒˆλ‘œμš΄ λ‚ μ§œ/μ‹œκ°„ API κ°€ 생긴 이유

  • κ·Έ μ „κΉŒμ§€ μ‚¬μš©ν•˜λ˜ java.util.Date ν΄λž˜μŠ€λŠ” mutable ν•˜κΈ° λ•Œλ¬Έμ— thead safe ν•˜μ§€ μ•ŠμŒ

  • 클래슀 이름이 λͺ…ν™•ν•˜μ§€ μ•ŠμŒ(Date 인데 μ‹œκ°„κΉŒμ§€ λ‹€λ£¨λŠ” λ“±..)

  • 버그가 λ°œμƒν•  μ—¬μ§€κ°€ 많음(νƒ€μž… μ•ˆμ •μ„±μ΄ μ—†κ³ , 월이 0λΆ€ν„° μ‹œμž‘ν•˜λŠ” λ“±..)

  • λ‚ μ§œ, μ‹œκ°„ μ²˜λ¦¬κ°€ λ³΅μž‘ν•œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œλŠ” 보톡 Joda Timearrow-up-right μ‚¬μš©

java 8 μ—μ„œ μ œκ³΅ν•˜λŠ” Date-Time API

  • JSR-310 슀팩arrow-up-right κ΅¬ν˜„μ²΄ 제곡

  • Design Principlesarrow-up-right

    • Clear: λ™μž‘μ΄ λͺ…ν™•ν•˜κ³  μ˜ˆμƒ κ°€λŠ₯

    • Fluent: μœ μ—°ν•œ μΈν„°νŽ˜μ΄μŠ€ 제곡. λ©”μ†Œλ“œ ν˜ΈμΆœμ„ μ—°κ²°ν•˜μ—¬ 간결함 제곡

    • Immutable: λΆˆλ³€ 객체 생성, thead safe

    • Extensible: ν™•μž₯ κ°€λŠ₯

μ£Όμš” API

  • κΈ°κ³„μš© μ‹œκ°„(machine time)κ³Ό 인λ₯˜μš© μ‹œκ°„(human time)으둜 ꡬ뢄

  • κΈ°κ³„μš© μ‹œκ°„

    • EPOCK(1970λ…„ 1μ›” 1일 0μ‹œ 0λΆ„ 0초)λΆ€ν„° ν˜„μž¬κΉŒμ§€μ˜ νƒ€μž„μŠ€νƒ¬ν”„λ₯Ό ν‘œν˜„

    • νƒ€μž„μŠ€νƒ¬ν”„λŠ” Instant μ‚¬μš©

  • 인λ₯˜μš© μ‹œκ°„

    • μš°λ¦¬κ°€ ν”νžˆ μ‚¬μš©ν•˜λŠ” μ—°,μ›”,일,μ‹œ,λΆ„,초 등을 ν‘œν˜„

    • νŠΉμ • λ‚ μ§œ(LocalDate), μ‹œκ°„(LocalTime), μΌμ‹œ(LocalDateTime) μ‚¬μš© κ°€λŠ₯

    • 기간을 ν‘œν˜„ν•  λ•ŒλŠ” Duration(μ‹œκ°„ 기반)κ³Ό Period(λ‚ μ§œ 기반) μ‚¬μš© κ°€λŠ₯

    • DateTimeFormatter λ₯Ό μ‚¬μš©ν•΄μ„œ μΌμ‹œλ₯Ό νŠΉμ •ν•œ λ¬Έμžμ—΄λ‘œ ν¬λ§€νŒ… κ°€λŠ₯

μ°Έκ³ 

.

DateTest.javaarrow-up-right

κΈ°κ³„μš© μ‹œκ°„(machine time) ν‘œν˜„

  • UTC(Universal Time Coordinated) == GMT(Greenwich Mean Time)

  • 보톡 μ‹œκ°„μ„ μž¬λŠ” 경우 μ‚¬μš©

인λ₯˜μš© μ‹œκ°„(human time) ν‘œν˜„

  • LocalDateTime.of(int, Month, int, int, int, int): 둜컬 νŠΉμ • μΌμ‹œ

  • ZonedDateTime.of(int, Month, int, int, int, int, ZoneId): νŠΉμ • Zone 의 νŠΉμ • μΌμ‹œ

λ‚ μ§œ μ—°μ‚°

κΈ°κ°„ ν‘œν˜„

Pasing/Formatting

λ ˆκ±°μ‹œ API 지원

  • GregorianCalendar, Date νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό Instant/ZonedDateTime 으둜 λ³€ν™˜ κ°€λŠ₯

  • java.util.TimeZone μ—μ„œ java.time.ZoneId 둜 μƒν˜Έ λ³€ν™˜ κ°€λŠ₯

CompletableFuture

Java Concurrency

Java Concurrencyarrow-up-right

Concurrent Software

  • λ™μ‹œμ— μ—¬λŸ¬ μž‘μ—…μ„ ν•  수 μžˆλŠ” μ†Œν”„νŠΈμ›¨μ–΄

Java Concurrency Programming

  • λ©€ν‹°ν”„λ‘œμ„Έμ‹±(ProcessBuilder)

  • λ©€ν‹°μ“°λ ˆλ“œ

Java multi-thread Programming

  • Thread / Runnable

μ“°λ ˆλ“œ μ£Όμš” κΈ°λŠ₯(examplearrow-up-right)

  • sleeparrow-up-right: ν˜„μž¬ μ“°λ ˆλ“œ λ©ˆμΆ”κΈ°

    • λ‹€λ₯Έ μ“°λ ˆλ“œκ°€ μ²˜λ¦¬ν•  수 μžˆλ„λ‘ 기회 제곡(락을 놓진 μ•ŠμŒ, λ°λ“œλ½ λ°œμƒ κ°€λŠ₯)

  • interruptarrow-up-right: λ‹€λ₯Έ μ“°λ ˆλ“œ 깨우기

    • λ‹€λ₯Έ μ“°λ ˆλ“œλ₯Ό κΉ¨μ›Œμ„œ interruptedExeption λ°œμƒ

  • joinarrow-up-right: λ‹€λ₯Έ μ“°λ ˆλ“œ λŒ€κΈ°

    • λ‹€λ₯Έ μ“°λ ˆλ“œκ°€ 끝날 λ•ŒκΉŒμ§€ λŒ€κΈ°

λ‹€μˆ˜μ˜ μŠ€λ ˆλ“œλ₯Ό μ½”λ”©μœΌλ‘œ κ΄€λ¦¬ν•˜κΈ° 어렀움. Execute 생성.

Executors

High-Level Concurrency Programming

  • μ“°λ ˆλ“œλ₯Ό μƒμ„±ν•˜κ³  κ΄€λ¦¬ν•˜λŠ” μž‘μ—…μ„ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ λΆ„λ¦¬ν•˜κ³  Executors μ—κ²Œ μœ„μž„

Executorsarrow-up-right 의 ν•˜λŠ” 일

  • μ“°λ ˆλ“œ 생성: μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ μ‚¬μš©ν•  μ“°λ ˆλ“œ 풀을 λ§Œλ“€μ–΄ 관리

  • μ“°λ ˆλ“œ 관리: μ“°λ ˆλ“œ 생λͺ… μ£ΌκΈ°λ₯Ό 관리

  • μž‘μ—… 처리 및 μ‹€ν–‰: μ“°λ ˆλ“œλ‘œ μ‹€ν–‰ν•  μž‘μ—…μ„ μ œκ³΅ν•  수 μžˆλŠ” API 제곡

μ£Όμš” μΈν„°νŽ˜μ΄μŠ€

  • Executor: execute(Runnable)

  • ExecutorService: Executor λ₯Ό 상속 받은 μΈν„°νŽ˜μ΄μŠ€

    • Callable, Runnable μ‹€ν–‰, Executor μ’…λ£Œ

    • μ—¬λŸ¬ Callable λ™μ‹œ μ‹€ν–‰ λ“±μ˜ κΈ°λŠ₯ 제곡

  • ScheduledExecutorService: ExecutorService λ₯Ό 상속 받은 μΈν„°νŽ˜μ΄μŠ€

    • νŠΉμ • μ‹œκ°„ 이후 λ˜λŠ” 주기적으둜 μž‘μ—… μ‹€ν–‰

examplearrow-up-right

Fork/Join ν”„λ ˆμž„μ›Œν¬

  • ExecutorService κ΅¬ν˜„μ²΄λ‘œ μ‰¬μš΄ λ©€ν‹° ν”„λ‘œμ„Έμ„œ ν™œμš© 지원

Callable & Future

Callable

  • Runnable κ³Ό μœ μ‚¬ν•˜μ§€λ§Œ μž‘μ—…μ˜ κ²°κ³Όλ₯Ό 리턴

Futurearrow-up-right

  • 비동기적인 μž‘μ—…μ˜ ν˜„μž¬ μƒνƒœλ₯Ό μ‘°νšŒν•˜κ±°λ‚˜ κ²°κ³Ό 리턴

CallableAndFuture.javaarrow-up-right

CompletableFuture

μžλ°”μ—μ„œ 비동기(Asynchronous) ν”„λ‘œκ·Έλž˜λ°μ΄ κ°€λŠ₯ν•˜λ„λ‘ μ§€μ›ν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€

  • Future λ‘œλ„ 비동기 μ²˜λ¦¬κ°€ μ–΄λŠμ •λ„ κ°€λŠ₯ν•˜μ§€λ§Œ, μ–΄λ €μš΄ μž‘μ—…λ“€μ΄ λ‹€μˆ˜ 쑴재

    • Future λ₯Ό μ™ΈλΆ€μ—μ„œ μ™„λ£Œ 처리 λΆˆκ°€

      • cancel(), get() νƒ€μž„μ•„μ›ƒ 섀정은 κ°€λŠ₯

    • λΈ”λ‘œν‚Ή μ½”λ“œ(ex. get())λ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šκ³ μ„œλŠ” μž‘μ—…μ΄ 끝났을 λ•Œ 콜백 μ‹€ν–‰ λΆˆκ°€

    • μ—¬λŸ¬ Future μ‘°ν•© λΆˆκ°€

      • ex. 행사 정보 쑰회 ν›„ 행사 참석 νšŒμ› λͺ©λ‘ μ‘°νšŒν•˜κΈ°

    • μ˜ˆμ™Έ 처리용 API 제곡 X

CompletableFuturearrow-up-right

.

λΉ„λ™κΈ°λ‘œ μž‘μ—… μ‹€ν–‰ν•˜κΈ°

.

콜백 μ œκ³΅ν•˜κΈ°

.

μ‘°ν•©ν•˜κΈ°

.

μ˜ˆμ™Έμ²˜λ¦¬

Etc..

μ• λ…Έν…Œμ΄μ…˜μ˜ λ³€ν™”

java 8 μ• λ…Έν…Œμ΄μ…˜ κ΄€λ ¨ 두 κ°€μ§€ 큰 λ³€ν™”

  • μ• λ…Έν…Œμ΄μ…˜μ„ νƒ€μž… μ„ μ–ΈλΆ€(μ œλ„€λ¦­ νƒ€μž…, λ³€μˆ˜ νƒ€μž…, λ§€κ°œλ³€μˆ˜ νƒ€μž…, μ˜ˆμ™Έ νƒ€μž…...)에도 μ‚¬μš© κ°€λŠ₯

    • TYPE_PARAMETER: νƒ€μž… λ³€μˆ˜μ—λ§Œ μ‚¬μš© κ°€λŠ₯

    • TYPE_USE: TYPE_PARAMETER 포함 λͺ¨λ“  νƒ€μž… 선언뢀에 μ‚¬μš© κ°€λŠ₯

  • μ• λ…Έν…Œμ΄μ…˜ 쀑볡 μ‚¬μš© κ°€λŠ₯

.

Array Parallel Sorting

Arrays.parallelSort()

  • Fork/Join ν”„λ ˆμž„μ›Œν¬λ₯Ό μ‚¬μš©ν•΄μ„œ 배열을 λ³‘λ ¬λ‘œ μ •λ ¬ν•˜λŠ” κΈ°λŠ₯ 제곡

  • 병렬 μ •λ ¬ μ•Œκ³ λ¦¬λ“¬

    • 배열을 λ‘˜λ‘œ 계속 μͺΌκ°  ν›„ ν•©μΉ˜λ©΄μ„œ μ •λ ¬

.

GC Metaspace

JVM의 μ—¬λŸ¬ λ©”λͺ¨λ¦¬ μ˜μ—­ 쀑에 PermGen λ©”λͺ¨λ¦¬ μ˜μ—­μ΄ μ—†μ–΄μ§€κ³  Metaspace μ˜μ—­μ΄ λ“±μž₯

PermGen(permanent generation)

Metaspace

  • 클래슀 메타데이터λ₯Ό λ‹΄λŠ” μ €μž₯μ†Œ(Heap μ˜μ—­μ΄ μ•„λ‹ˆλΌ, Native Memory μ˜μ—­)

  • κΈ°λ³Έκ°’μœΌλ‘œ μ œν•œλœ 크기λ₯Ό κ°€μ§€κ³  μžˆμ§€ μ•ŠμŒ(ν•„μš”ν•œ 만큼 계속 증가)

  • java 8 λΆ€ν„°λŠ” PermGen κ΄€λ ¨ μ˜΅μ…˜μ€ λ¬΄μ‹œ

μ°Έκ³ 

JVM

JAVA, JVM, JDK, JRE

Result

JVM(Java Virtual Machine)

  • μžλ°” λ°”μ΄νŠΈ μ½”λ“œ(.class)λ₯Ό OS νŠΉν™”λœ μ½”λ“œλ‘œ λ³€ν™˜(인터프리터와 JIT 컴파일러)ν•˜μ—¬ μ‹€ν–‰

    • νŠΉμ • ν”Œλž«νΌμ— 쒅속적

  • λ°”μ΄νŠΈ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λŠ” ν‘œμ€€(JVM μžμ²΄λŠ” ν‘œμ€€)이자 κ΅¬ν˜„μ²΄(νŠΉμ • 밴더가 κ΅¬ν˜„ν•œ JVM)

    • JVM 밴더: Oracle, Amazon, Azul, ...

JRE(Java Runtime Environment): JVM + Library

  • μžλ°” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ‹€ν–‰ν•  수 μžˆλ„λ‘ κ΅¬μ„±λœ 배포판

  • JVM κ³Ό 핡심 라이브러리 및 μžλ°” λŸ°νƒ€μž„ ν™˜κ²½μ—μ„œ μ‚¬μš©ν•˜λŠ” ν”„λ‘œνΌν‹° μ„ΈνŒ…μ΄λ‚˜ λ¦¬μ†ŒμŠ€ 파일 보유

  • 개발 κ΄€λ ¨ λ„κ΅¬λŠ” 미포함(JDKμ—μ„œ 제곡)

JDK(Java Development Kit): JRE + Development Tool

  • μ†ŒμŠ€ μ½”λ“œλ₯Ό μž‘μ„±ν•  λ•Œ μ‚¬μš©ν•˜λŠ” μžλ°” μ–Έμ–΄λŠ” ν”Œλž«νΌμ— 독립적

  • μ˜€λΌν΄μ€ μžλ°” 11λΆ€ν„°λŠ” JDK 만 μ œκ³΅ν•˜λ©° JRE 미제곡

  • Write Once Run Anywhere(WORA, ν•œ 번만 μž‘μ„±ν•˜λ©΄ μ–΄λ””μ—μ„œλ“  μ‹€ν–‰ κ°€λŠ₯)

JAVA

  • ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄

  • JDK 에 λ“€μ–΄μžˆλŠ” μžλ°” 컴파일러(javac)λ₯Ό μ‚¬μš©ν•˜μ—¬ λ°”μ΄νŠΈμ½”λ“œ(.class)둜 컴파일 κ°€λŠ₯

  • μžλ°” μœ λ£Œν™”arrow-up-right? μ˜€λΌν΄μ—μ„œ λ§Œλ“  Oracle JDK 11 버전뢀터 μƒμš©μœΌλ‘œ μ‚¬μš© μ‹œμ—λ§Œ 유료

JVM μ–Έμ–΄

  • JVM 기반으둜 λ™μž‘ν•˜λŠ” ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄

  • Clojure, Groovy, JRuby, Jython, Kotlin, Scala, ...

μ°Έκ³ 

.

JVM ꡬ쑰

Result

Class Loader System

  • .class μ—μ„œ λ°”μ΄νŠΈμ½”λ“œλ₯Ό 읽고 λ©”λͺ¨λ¦¬μ— μ €μž₯

  • loading: 클래슀 μ½μ–΄μ˜€λŠ” κ³Όμ •

  • linking: 레퍼런슀λ₯Ό μ—°κ²°ν•˜λŠ” κ³Όμ •

  • initialization: static 값듀을 μ΄ˆκΈ°ν™” 및 λ³€μˆ˜μ— ν• λ‹Ή

Memory

Java JVM Run-time Data Areasarrow-up-right

  • Stack Area

    • μ“°λ ˆλ“œλ§ˆλ‹€ λŸ°νƒ€μž„ μŠ€νƒμ„ λ§Œλ“€κ³ , κ·Έ μ•ˆμ— λ©”μ†Œλ“œ ν˜ΈμΆœμ„ μŠ€νƒ ν”„λ ˆμž„μ΄λΌ λΆ€λ₯΄λŠ” λΈ”λŸ­μœΌλ‘œ μŒ“μŒ

    • μ“°λ ˆλ“œλ₯Ό μ’…λ£Œν•˜λ©΄ λŸ°νƒ€μž„ μŠ€νƒλ„ μ†Œλ©Έ(μ“°λ ˆλ“œμ—μ„œλ§Œ 곡유)

  • PC(Program Counter) registers Area

    • μ“°λ ˆλ“œλ§ˆλ‹€ μ“°λ ˆλ“œ λ‚΄ ν˜„μž¬ μ‹€ν–‰ν•  instruction μœ„μΉ˜λ₯Ό κ°€λ¦¬ν‚€λŠ” 포인터 생성(μ“°λ ˆλ“œμ—μ„œλ§Œ 곡유)

  • native method stack Area

    • μ“°λ ˆλ“œλ§ˆλ‹€ μƒμ„±λ˜κ³ , native method 호좜 μ‹œ μ‚¬μš©ν•˜λŠ” λ³„λ„μ˜ method stack(μ“°λ ˆλ“œμ—μ„œλ§Œ 곡유)

  • heap Area

    • 객체 μ €μž₯(곡유 μžμ›)

  • method Area

    • 클래슀 μˆ˜μ€€μ˜ 정보(클래슀 이름, νŒ¨ν‚€μ§€ 경둜, λΆ€λͺ¨ 클래슀 이름, λ©”μ†Œλ“œ, λ³€μˆ˜)μ €μž₯(곡유 μžμ›)

Execution Engine

  • 인터프리터

    • λ°”μ΄νŠΈ μ½”λ“œλ₯Ό ν•œμ€„μ”© μ‹€ν–‰

  • JIT(Just-In-Time) 컴파일러

    • 인터프리터 νš¨μœ¨μ„ 높이기 μœ„ν•΄ 인터프리터가 λ°˜λ³΅λ˜λŠ” μ½”λ“œλ₯Ό λ°œκ²¬ν•˜λ©΄ JIT 컴파일러둜 λ°˜λ³΅λ˜λŠ” μ½”λ“œλ₯Ό λ„€μ΄ν‹°λΈŒ μ½”λ“œλ‘œ λ³€κ²½

    • κ·Έ λ‹€μŒλΆ€ν„° μΈν„°ν”„λ¦¬ν„°λŠ” λ„€μ΄ν‹°λΈŒ μ½”λ“œλ‘œ 컴파일된 μ½”λ“œλ₯Ό λ°”λ‘œ μ‚¬μš©

  • GC(Garbage Collector)

    • 더이상 μ°Έμ‘°λ˜μ§€ μ•ŠλŠ” 객체λ₯Ό λͺ¨μ•„μ„œ 정리

JNI(Java Native Interface)

Native Method Library

  • C, C++둜 μž‘μ„±λœ 라이브러리

  • JNI λ₯Ό 톡해 μ‚¬μš©

μ°Έκ³ 

.

Class Loader System

λ‘œλ”©, 링크, μ΄ˆκΈ°ν™” 순으둜 μ§„ν–‰

Result

Loading

  • 클래슀 λ‘œλ”κ°€ .class νŒŒμΌμ„ 읽고 κ·Έ λ‚΄μš©μ— 따라 μ μ ˆν•œ λ°”μ΄λ„ˆλ¦¬ 데이터λ₯Ό λ§Œλ“€κ³  Method Memory μ˜μ—­μ— μ €μž₯

  • Method Memory μ˜μ—­μ— μ €μž₯ν•˜λŠ” 데이터

    • FQCN(Full Qualified Class Name)

    • 클래슀/μΈν„°νŽ˜μ΄μŠ€/μ΄λŠ„

    • λ©”μ†Œλ“œμ™€ λ³€μˆ˜

  • λ‘œλ”©μ΄ λλ‚˜λ©΄ ν•΄λ‹Ή 클래슀 νƒ€μž…μ˜ Class 객체λ₯Ό μƒμ„±ν•˜μ—¬ Heap μ˜μ—­μ— μ €μž₯

클래슀 λ‘œλ”λŠ” 계측 ꡬ쑰둜 이뀄져 있으면 기본적으둜 μ„Έκ°€μ§€ 클래슀 λ‘œλ”κ°€ 제곡

  • BootstrapClassLoader

    • μ΅œμƒμœ„ μš°μ„ μˆœμœ„λ₯Ό κ°€μ§„ 클래슀 λ‘œλ”

    • JAVA_HOME\lib 에 μžˆλŠ” μ½”μ–΄ μžλ°” API 제곡

  • PlatformClassLoader

    • JAVA_HOME\lib\ext 폴더 λ˜λŠ” java.ext.dirs μ‹œμŠ€ν…œ λ³€μˆ˜μ— ν•΄λ‹Ήν•˜λŠ” 클래슀λ₯Ό 읽음

  • AppClassLoader

    • μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 클래슀 νŒ¨μŠ€μ—μ„œ 클래슀λ₯Ό 읽음

    • 클래슀 패슀: μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ‹€ν–‰ μ‹œ -classpath μ˜΅μ…˜ λ˜λŠ” java.class.path ν™˜κ²½ λ³€μˆ˜ 값에 ν•΄λ‹Ήν•˜λŠ” μœ„μΉ˜

μ΅œμƒμœ„ 클래슀 λ‘œλ”λΆ€ν„° 클래슀λ₯Ό μ°Έμƒ‰ν•˜λŠ”λ° λͺ¨λ“  클래슀 λ‘œλ”κ°€ 클래슀λ₯Ό μ°Ύμ§€ λͺ» ν•œλ‹€λ©΄ ClassNotFoundException λ°œμƒ

Linking

  • Verify: .class 파일 ν˜•μ‹μ΄ μœ νš¨ν•œμ§€ 체크

  • Preparation: 클래슀 λ³€μˆ˜(static λ³€μˆ˜)와 기본값에 ν•„μš”ν•œ λ©”λͺ¨λ¦¬ μ€€λΉ„

  • Resolve(optional): 심볼릭 λ©”λͺ¨λ¦¬ 레퍼런슀λ₯Ό λ©”μ†Œλ“œ μ˜μ—­μ— μžˆλŠ” μ‹€μ œ 레퍼런슀둜 ꡐ체

Initialization

  • Static λ³€μˆ˜μ˜ 값을 ν• λ‹Ή(static λΈ”λŸ­μ΄ μžˆλ‹€λ©΄ μ΄λ•Œ μ‹€ν–‰)

Bytecode Operation

μ½”λ“œ 컀버리지 μΈ‘μ •

.

클래슀 λ‘œλ”© μ „ λ°”μ΄νŠΈμ½”λ“œ μ‘°μž‘

ν”„λ‘œκ·Έλž¨ 뢄석

  • μ½”λ“œμ—μ„œ 버그λ₯Ό μ°ΎλŠ” 툴

  • μ½”λ“œ λ³΅μž‘λ„ 계산

클래슀 파일 생성

  • ν”„λ‘μ‹œ

  • νŠΉμ • API 호좜 μ ‘κ·Ό μ œν•œ

  • 슀칼라 같은 μ–Έμ–΄μ˜ 컴파일러

그밖에도 μžλ°” μ†ŒμŠ€μ½”λ“œλ₯Ό κ±΄λ“œλ¦¬μ§€ μ•Šκ³  μ½”λ“œ 변경이 ν•„μš”ν•œ μ—¬λŸ¬ κ²½μš°μ— μ‚¬μš© κ°€λŠ₯

  • ν”„λ‘œνŒŒμΌλŸ¬: CPU μ‚¬μš©λ₯  및 λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰, Thread 정보 ..

  • μ΅œμ ν™”

  • λ‘œκΉ…

  • ...

μŠ€ν”„λ§μ˜ λ°”μ΄νŠΈμ½”λ“œ μ‘°μž‘ 툴 μ‚¬μš©: μŠ€ν”„λ§ μ»΄ν¬λ„ŒνŠΈ μŠ€μΊ”

  • 빈으둜 등둝할 후보 클래슀 정보λ₯Ό μ°ΎλŠ”λ° ASM μ‚¬μš©

  • ClassPathScanningCandidateComponentProvider -> SimpleMetadataReader

  • ClassReader, Visitor λ₯Ό μ‚¬μš©ν•΄μ„œ ν΄λž˜μŠ€μ— μžˆλŠ” 메타 정보 쑰회

μ°Έκ³ 

.

λ°”μ΄νŠΈμ½”λ“œ μ‘°μž‘ 라이브러리

  • ByteBuddyarrow-up-right

    • .class 파일 자체λ₯Ό λ³€κ²½μ‹œν‚€λŠ” 방법

    • ꢌμž₯ν•˜λŠ” 라이브러리

  • Javassistarrow-up-right

    • 클래슀 λ‘œλ”κ°€ 클래슀λ₯Ό μ½μ–΄μ˜¬ λ•Œ javaagent λ₯Ό κ±°μ³μ„œ λ³€κ²½λœ λ°”μ΄νŠΈμ½”λ“œλ₯Ό μ½μ–΄μ˜΄

      • premain: μ‹œμž‘ μ‹œ λΆ™μ΄λŠ” 방식

      • agentmain: λŸ°νƒ€μž„ 쀑 λ™μ μœΌλ‘œ λΆ™μ΄λŠ” 방식

  • CGlib

Reflection

λ¦¬ν”Œλ ‰μ…˜μ˜ μ‹œμž‘μ€ Class<T>arrow-up-right

Class<T> μ ‘κ·Ό 방법

  • λͺ¨λ“  클래슀λ₯Ό λ‘œλ”© ν•œ λ‹€μŒ Class<T> μΈμŠ€ν„΄μŠ€ 생성

    • νƒ€μž….class 둜 μ ‘κ·Ό κ°€λŠ₯

  • λͺ¨λ“  μΈμŠ€ν„΄μŠ€λŠ” getClass() λ©”μ†Œλ“œ 보유

    • μΈμŠ€ν„΄μŠ€.getClass() 둜 μ ‘κ·Ό κ°€λŠ₯

  • 클래슀λ₯Ό λ¬Έμžμ—΄λ‘œ μ½μ–΄μ˜€λŠ” 방법

    • Class.forName("FQCN")

    • ν΄λž˜μŠ€νŒ¨μŠ€μ— ν•΄λ‹Ή ν΄λž˜μŠ€κ°€ μ—†λ‹€λ©΄ ClassNotFoundException λ°œμƒ

Class<T> λ₯Ό 톡해 ν•  수 μžˆλŠ” 것

  • ν•„λ“œ(λͺ©λ‘) κ°€μ Έμ˜€κΈ°

  • λ©”μ†Œλ“œ(λͺ©λ‘) κ°€μ Έμ˜€κΈ°

  • μƒμœ„ 클래슀 κ°€μ Έμ˜€κΈ°

  • μΈν„°νŽ˜μ΄μŠ€(λͺ©λ‘) κ°€μ Έμ˜€κΈ°

  • μ• λ…Έν…Œμ΄μ…˜ κ°€μ Έμ˜€κΈ°

  • μƒμ„±μž κ°€μ Έμ˜€κΈ° ...

.

Annotation & Reflection

Annotaion

  • @Retention: ν•΄λ‹Ή μ• λ…Έν…Œμ΄μ…˜μ„ μ–Έμ œκΉŒμ§€ μœ μ§€ν•  것인가. (SOURCE, CLASS, RUNTIME)

  • @Target: 어디에 μ‚¬μš©ν•  수 μžˆλŠ”κ°€. (TYPE, FIELD, METHOD, PARAMETER ..)

  • @Inherit: ν•΄λ‹Ή μ• λ…Έν…Œμ΄μ…˜μ„ ν•˜μœ„ ν΄λž˜μŠ€κΉŒμ§€ 전달할 것인가.

Reflection

  • getAnnotations(): 상속받은(@Inherit) μ• λ…Έν…Œμ΄μ…˜κΉŒμ§€ 쑰회

  • getDeclaredAnnotations(): 자기 μžμ‹ μ—λ§Œ λΆ™μ–΄μžˆλŠ” μ• λ…Έν…Œμ΄μ…˜ 쑰회

.

Edit class information or Run

BallTestarrow-up-right

.

Reflection 을 ν™œμš©ν•˜μ—¬ κ°„λ‹¨ν•œ DI ν”„λ ˆμž„μ›Œν¬ λ§Œλ“€μ–΄λ³΄κΈ°

@Inject μ„ μ–ΈμœΌλ‘œ ν•„λ“œ μ£Όμž…μ„ ν•΄μ£ΌλŠ” μ»¨ν…Œμ΄λ„ˆ μ„œλΉ„μŠ€arrow-up-right

ContainerService.getObject

  • classType 에 ν•΄λ‹Ήν•˜λŠ” νƒ€μž…μ˜ 객체 생성

  • ν•΄λ‹Ή 객체의 ν•„λ“œ 쀑에 @Inject κ°€ μžˆλ‹€λ©΄ ν•΄λ‹Ή ν•„λ“œλ„ 같이 λ§Œλ“€μ–΄ 제곡

.

Reflection 정리

λ¦¬ν”Œλ ‰μ…˜ μ‚¬μš© μ‹œ 주의

  • μ§€λ‚˜μΉœ μ‚¬μš©(λ¬΄λΆ„λ³„ν•œ μΈμŠ€ν„΄μŠ€ μƒμ„±μœΌλ‘œ)은 μ„±λŠ₯ 이슈λ₯Ό μ•ΌκΈ°ν•  수 μžˆμœΌλ―€λ‘œ λ°˜λ“œμ‹œ ν•„μš”ν•œ κ²½μš°μ—λ§Œ μ‚¬μš© ꢌμž₯

  • 컴파일 νƒ€μž„μ— ν™•μΈλ˜μ§€ μ•Šκ³  λŸ°νƒ€μž„ μ‹œμ—λ§Œ λ°œμƒν•˜λŠ” 문제λ₯Ό λ§Œλ“€ κ°€λŠ₯μ„± 쑴재

  • μ ‘κ·Ό μ§€μ‹œμž λ¬΄μ‹œ

λ¦¬ν”Œλ ‰μ…˜ μ‚¬μš© 사둀

  • Spring.

    • μ˜μ‘΄μ„± μ£Όμž…

    • MVC View μ—μ„œ λ„˜μ–΄μ˜¨ 데이터λ₯Ό 객체에 바인딩 ν•  λ•Œ

  • Hibernate.

    • @Entity ν΄λž˜μŠ€μ— Setter κ°€ μ—†λ‹€λ©΄ λ¦¬ν”Œλ ‰μ…˜ μ‚¬μš©

Reference.

Dynamic Proxy

λŸ°νƒ€μž„μ— μΈν„°νŽ˜μ΄μŠ€/클래슀의 ν”„λ‘μ‹œ μΈμŠ€ν„΄μŠ€/클래슀λ₯Ό λ§Œλ“€μ–΄ μ‚¬μš©ν•˜λŠ” ν”„λ‘œκ·Έλž˜λ° 기법

Spring Data JPA λŠ” μ–΄λ–»κ²Œ λ™μž‘ν• κΉŒ?

  • μΈν„°νŽ˜μ΄μŠ€ νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€λŠ” λˆ„κ°€ λ§Œλ“€μ–΄ μ€„κΉŒ?

    • JpaRepository μΈν„°νŽ˜μ΄μŠ€λ₯Ό μƒμ†λ°›μœΌλ©΄ 객체도 μƒμ„±λ˜κ³ , 빈으λ₯΄λ„ 등둝

  • Spring AOP 기반으둜 λ™μž‘ν•˜λ©° RepositoryFactorySupport μ—μ„œ ν”„λ‘μ‹œ 객체 생성

    • μƒμ„±λœ ν”„λ‘μ‹œ 객체가 빈으둜 λ“±λ‘λ˜κ³  μ£Όμž…

Dynamic Proxy μ‚¬μš© 예

  • Spring Data JPA

  • Spring AOP

  • Mockito

  • Hibernate lazy initialzation ...

.

Proxy Pattern

Result
  • ν”„λ‘μ‹œμ™€ 리얼 μ„œλΈŒμ νŠΈκ°€ κ³΅μœ ν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€κ°€ 있고, ν΄λΌμ΄μ–ΈνŠΈλŠ” ν•΄λ‹Ή μΈν„°νŽ˜μ΄μŠ€ νƒ€μž…μœΌλ‘œ ν”„λ‘μ‹œ μ‚¬μš©

  • ν΄λΌμ΄μ–ΈνŠΈλŠ” ν”„λ‘μ‹œλ₯Ό κ±°μ³μ„œ 리얼 μ„œλΈŒμ νŠΈλ₯Ό μ‚¬μš©

    • ν”„λ‘μ‹œλŠ” 리얼 μ„œλΈŒμ νŠΈμ— λŒ€ν•œ μ ‘κ·Ό 관리, λΆ€κ°€ κΈ°λŠ₯ 제곡, 리턴값 λ³€κ²½ κ°€λŠ₯

  • 리얼 μ„œλΈŒμ  νŠΈλŠ” μžμ‹ μ΄ ν•΄μ•Ό ν•  일만 ν•˜λ©΄μ„œ(SRParrow-up-right) ν”„λ‘μ‹œ μ‚¬μš©

단점

  • ν”„λ‘μ‹œ νŒ¨ν„΄μœΌλ‘œ κ΅¬ν˜„ν•˜λŠ” 것은 번거둜운 일

  • 뢀가적인 κΈ°λŠ₯을 μΆ”κ°€ν•  λ•Œλ§ˆλ‹€ 별도 ν”„λ‘μ‹œ 생성 ν•„μš”

  • ν”„λ‘μ‹œλ‘œ ν”„λ‘μ‹œλ₯Ό 감싸야 ν•˜λŠ” 일도 λ°œμƒ

  • λͺ¨λ“  κ΅¬ν˜„μ²΄μ—μ„œ μ›λž˜ νƒ€κ²ŸμœΌλ‘œ μœ„μž„ν•˜λ©΄μ„œ 쀑볡 μ½”λ“œ λ°œμƒ

Proxy Pattern examplearrow-up-right

ν”„λ‘μ‹œ νŒ¨ν„΄μ˜ 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ λ™μ μœΌλ‘œ λŸ°νƒ€μž„μ— ν”„λ‘μ‹œλ₯Ό μƒμ„±ν•΄λ‚΄λŠ” λ‹€μ΄λ‚˜λ―Ή ν”„λ‘μ‹œ λ“±μž₯

.

Dynamic Proxy

λŸ°νƒ€μž„μ— νŠΉμ • μΈν„°νŽ˜μ΄μŠ€λ“€μ„ κ΅¬ν˜„ν•˜λŠ” 클래슀 λ˜λŠ” μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“œλŠ” 기술

단점.

  • 클래슀 기반의 ν”„λ‘μ‹œ 생성 λΆˆκ°€ -> μΈν„°νŽ˜μ΄μŠ€κ°€ 없을 경우 λ‹€μ΄λ‚˜λ―Ή ν”„λ‘μ‹œ 적용 λΆˆκ°€

  • λΆ€κ°€κΈ°λŠ₯이 λ§Žμ•„μ§ˆμˆ˜λ‘ μ½”λ“œκ°€ μ»€μ§€λŠ” μœ μ—°ν•˜μ§€ μ•Šμ€ ꡬ쑰

ν”„λ‘μ‹œ 기반 AOP 인 μŠ€ν”„λ§ AOP λ“±μž₯

.

Class Proxy

μΈν„°νŽ˜μ΄μŠ€ 없이 ν”„λ‘μ‹œ λ§Œλ“€κΈ°

CGlibarrow-up-right

  • Spring, Hibernate μ—μ„œλ„ μ‚¬μš©ν•˜λŠ” 라이브러리

  • 버전 ν˜Έν™˜μ„±μ΄ μ’‹μ§€ μ•Šμ•„μ„œ μ„œλ‘œ λ‹€λ₯Έ 라이브러리 내뢀에 λ‚΄μž₯된 ν˜•νƒœλ‘œ μ œκ³΅λ˜κΈ°λ„ 함

ByteBuddyarrow-up-right

  • λ°”μ΄νŠΈ μ½”λ“œ μ‘°μž‘ 뿐 μ•„λ‹ˆλΌ λŸ°νƒ€μž„(λ‹€μ΄λ‚˜λ―Ή) ν”„λ‘μ‹œ 생성 μ‹œμ—λ„ μ‚¬μš©

μΈν„°νŽ˜μ΄μŠ€ 없이 ν”„λ‘μ‹œλ₯Ό 생성할 경우 단점

  • 상속을 μ‚¬μš©ν•˜μ§€ λͺ»ν•˜λŠ” 경우 ν”„λ‘μ‹œ 생성 λΆˆκ°€

    • Final 클래슀인 경우

    • Private μƒμ„±μžλ§Œ μžˆλŠ” 경우

가급적 ν”„λ‘μ‹œ 적용 μ‹œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ§Œλ“€μ–΄μ„œ μΈν„°νŽ˜μ΄μŠ€ ν”„λ‘μ‹œλ₯Ό μ‚¬μš©ν•˜λŠ” 것을 ꢌμž₯

Annotation processor

μ• λ…Έν…Œμ΄μ…˜ ν”„λ‘œμ„Έμ„œ μ‚¬μš© 예

  • Lombok

    • ν‘œμ€€μœΌλ‘œ μž‘μ„±ν•΄μ•Ό ν•˜λŠ” μ½”λ“œλ₯Ό 개발자 λŒ€μ‹  생성해 μ£ΌλŠ” 라이브러리

  • AutoService

    • java.util.ServiceLoader 용 파일 생성 μœ ν‹Έλ¦¬ν‹°

  • @Override

  • Daggerarrow-up-right

    • 컴파일 νƒ€μž„ DI 제곡

μž₯점

  • λŸ°νƒ€μž„ λΉ„μš©μ΄ 제둜

단점

  • κΈ°μ‘΄ 클래슀 μ½”λ“œλ₯Ό λ³€κ²½ν•  λ•ŒλŠ” μ•½κ°„μ˜ hack ν•„μš”

.

Lombok

  • @Getter, @Setter λ“±μ˜ μ• λ…Έν…Œμ΄μ…˜κ³Ό μ• λ…Έν…Œμ΄μ…˜ ν”„λ‘œμ„Έμ„œλ₯Ό μ œκ³΅ν•˜μ—¬ ν‘œμ€€ μž‘μ„± μ½”λ“œλ₯Ό 개발자 λŒ€μ‹  μƒμ„±ν•΄μ£ΌλŠ” 라이브러리

둬볡의 λ™μž‘ 원리

둬볡의 λ…Όλž€ 거리

  • 곡개된 API κ°€ μ•„λ‹Œ 컴파일러 λ‚΄λΆ€ 클래슀λ₯Ό μ‚¬μš©ν•˜μ—¬ κΈ°μ‘΄ μ†ŒμŠ€ μ½”λ“œλ₯Ό μ‘°μž‘

  • 특히 이클립슀의 κ²½μš°μ—” java agent λ₯Ό μ‚¬μš©ν•˜μ—¬ 컴파일러 ν΄λž˜μŠ€κΉŒμ§€ μ‘°μž‘ν•˜μ—¬ μ‚¬μš©

  • ν•΄λ‹Ή ν΄λž˜μŠ€λ“€ μ—­μ‹œ 곡개된 API κ°€ μ•„λ‹ˆλ‹€λ³΄λ‹ˆ 버전 ν˜Έν™˜μ„±μ— λ¬Έμ œκ°€ 생길 수 있음

  • κ·ΈλŸΌμ—λ„ μ—„μ²­λ‚œ νŽΈλ¦¬ν•¨μœΌλ‘œ 널리 쓰이고, λŒ€μ•ˆμ΄ λͺ‡κ°€μ§€ μžˆμ§€λ§Œ 둬볡의 λͺ¨λ“  κΈ°λŠ₯κ³Ό νŽΈμ˜μ„±μ„ λŒ€μ²΄ λΆˆκ°€

.

Annotation processor

Processor Interfacearrow-up-right

  • μ—¬λŸ¬ λΌμš΄λ“œ(rounds)에 거쳐 μ†ŒμŠ€ 및 컴파일 된 μ½”λ“œλ₯Ό 처리

AutoService

  • ServiceProviderarrow-up-right λ ˆμ§€μŠ€νŠΈλ¦¬ 생성기

  • 컴파일 μ‹œμ μ— μ• λ…Έν…Œμ΄μ…˜ ν”„λ‘œμ„Έμ„œλ₯Ό μ‚¬μš©ν•˜μ—¬ META-INF/services/javax.annotation.processor.Processor 파일 μžλ™ 생성

javapoet

Interface Filer

  • μ†ŒμŠ€ μ½”λ“œ, 클래슀 μ½”λ“œ 및 λ¦¬μ†ŒμŠ€λ₯Ό 생성할 수 μžˆλŠ” μΈν„°νŽ˜μ΄μŠ€

μ°Έκ³ .

Last updated