Skip to content

Latest commit

ย 

History

History
384 lines (317 loc) ยท 13.1 KB

File metadata and controls

384 lines (317 loc) ยท 13.1 KB

์–ด๋…ธํ…Œ์ด์…˜๊ณผ ๋ฉ”ํƒ€์ŠคํŽ˜์ด์Šค

1. ์ œ๋„ค๋ฆญํƒ€์ž… ์„ ์–ธ๋ถ€์—๋„ ์‚ฌ์šฉ๊ฐ€๋Šฅ

  • ๊ธฐ์กด์˜ ์–ด๋…ธํ…Œ์ด์…˜ Target ์ข…๋ฅ˜

    • TYPE : ํด๋ž˜์Šค / ์ธํ„ฐํŽ˜์ด์Šค / ์–ด๋…ธํ…Œ์ด์…˜ / enum / record์˜ ์„ ์–ธ๋ถ€
    • ANNOTATION_TYPE : ์–ด๋…ธํ…Œ์ด์…˜์˜ ์„ ์–ธ๋ถ€
    • FIELD : ํด๋ž˜์Šค๋‚ด์˜ ๋‚ด๋ถ€ํ•„๋“œ์˜ ์„ ์–ธ๋ถ€
    • METHOD : ํด๋ž˜์Šค๋‚ด์˜ ๋ฉ”์„œ๋“œ์˜ ์„ ์–ธ๋ถ€
    • PARAMETER : ๋ฉ”์„œ๋“œ๋‚ด์˜ ํŒŒ๋ฆฌ๋ฏธํ„ฐ์˜ ์„ ์–ธ๋ถ€
    • CONSTRUCT : ์ƒ์„ฑ์ž์˜ ์„ ์–ธ๋ถ€
    • LOCAL_VARIABLE : ์ง€์—ญ๋ณ€์ˆ˜์˜ ์„ ์–ธ๋ถ€
    • PAKCAGE : ํ•ด๋‹น ํŒจํ‚ค์ง€์˜ packge-info.java์— ๋ถ™์ผ ์ˆ˜ ์žˆ๋‹ค.
  • java8์— ์ถ”๊ฐ€๋œ Target

    • ์œ„์˜ ์–ด๋…ธํ…Œ์ด์…˜๋“ค๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ ์„ ์–ธ ์ฃผ์„์ด ์•„๋‹Œ TYPE ์ฃผ์„์ด๋‹ค.

      • ์„ ์–ธ ์ฃผ์„ : ์ฃผ์˜์‚ฌํ•ญ, ์‚ฌ์šฉ๋ฐฉ๋ฒ•, ์‚ฌ์šฉ์ฒ˜ ๋“ฑ ์„ค๋ช…
      • TYPE ์ฃผ์„ : ์ •์ˆ˜ ๊ฐ’์ด 0๋ณด๋‹ค ์ปค์•ผ ํ•œ๋‹ค, null์ด ์•„๋‹ˆ๋‹ค ์™€ ๊ฐ™์€ ๊ฐ’์— ๋Œ€ํ•œ ์ •๋ณด ์ œ๊ณตํ•จ์œผ๋กœ์จ implements, thorws, new ๊ตฌ์ ˆ์— ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์ œ๋„ค๋ฆญ์— ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ์™ธ๋ถ€์˜ ํ”„๋กœ์ ํŠธ์—๋„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ™•์žฅํ•œ ๋ฒ”์œ„
    • TYPE_PARAMETER : ํƒ€์ž… ์„ ์–ธ๋ถ€์— ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅ

      //annotation
      @Retention(RetentionPolicy.RUNTIME)
      @Target(ElementType.TYPE_PARAMETER)
      public @interface ParmeterEx {
      }
      
      //class์— ์‚ฌ์šฉ
      public class AnnotationStudy <@ParmeterEx T> {
          public void print( T t){}
      }
      
      //method์— ์‚ฌ์šฉ
      public class AnnotationStudy {
          public <@ParmeterEx T> void print( T t){}
      }
      
      //method์— ์‚ฌ์šฉ
      public class AnnotationStudy {
          public <@ParmeterEx T> void print(T t) throws @ParameterEx SomthingException{}
      }
      
      //BYTE CODE
      public class study/AnnotationStudy {
          // compiled from: AnnotationStudy.java
      
          @Lstudy/ParmeterEx;() : CLASS_TYPE_PARAMETER 0, null
      
          // access flags 0x0
          Ljava/lang/String; name
      
          // access flags 0x1
          public <init>()V
          L0
              LINENUMBER 3 L0
              ALOAD 0
              INVOKESPECIAL java/lang/Object.<init> ()V
          L1
              LINENUMBER 4 L1
              ALOAD 0
              LDC "default"
              PUTFIELD study/AnnotationStudy.name : Ljava/lang/String;
              RETURN
          L2
              LOCALVARIABLE this Lstudy/AnnotationStudy; L0 L2 0
              // signature Lstudy/AnnotationStudy<TT;>;
              // declaration: this extends study.AnnotationStudy<T>
              MAXSTACK = 2
              MAXLOCALS = 1
      
          // access flags 0x1
          // signature <R:Ljava/lang/Object;>()V
          // declaration: void print<R>()
          public print()V
          @Lstudy/ParmeterEx;() : METHOD_TYPE_PARAMETER 0, null

      ์ปดํŒŒ์ผํ•˜๋ฉด์„œ ํ•ด๋‹น ํƒ€์ž…์ด ๋ฌด์Šจ ํƒ€์ž…์ธ์ง€ ๋ถ„์„ํ•˜์—ฌ CLASS_TYPE_PARAMETER / METHOD_TYPE_PARAMETER ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

      ํƒ€์ž… ์„ ์–ธ๋ถ€์— ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•œ Target์ด๋ฏ€๋กœ ์•„๋ž˜์™€ ๊ฐ™์ด ์‹ค์ œ ์‚ฌ์šฉํ•˜๋Š” ๋ถ€๋ถ„์—๋Š” ์ ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

      public class AnnotationStudy {
          public <T> void print(@ParmeterEx T a){}
      }
      • TYPE_USE : ์„ ์–ธ๋ถ€ ๋ฟ๋งŒ์ด ์•„๋‹Œ ํƒ€์ž… ์‚ฌ์šฉ๋˜๋Š” ๋ชจ๋“ ๊ณณ์— ์ ์šฉ์ด ๊ฐ€๋Šฅ(ํด๋ž˜์Šค/์ธํ„ฐํŽ˜์ด์Šค/๋‚ด๋ถ€ํ•„๋“œ/ํŒŒ๋ผ๋ฏธํ„ฐ/์ œ๋„ค๋ฆญ/์ง€์—ญ๋ณ€์ˆ˜ ๋“ฑ)

        @Retention(RetentionPolicy.RUNTIME)
        @Target(ElementType.TYPE_USE)
        public @interface ParmeterEx {
        }
        
        @ParmeterEx
        public class AnnotationStudy <@ParmeterEx T>{
            @ParmeterEx
            String name = "default";
        
            @NonNull
            public <@ParmeterEx R> void print(@ParmeterEx String t, @ParmeterEx R r){
                @ParmeterEx
                int a=1;
            }
        }
        
        //byte code
        // class version 61.0 (61)
        // access flags 0x21
        // signature <T:Ljava/lang/Object;>Ljava/lang/Object;
        // declaration: study/AnnotationStudy<T>
        public class study/AnnotationStudy {
        
        // compiled from: AnnotationStudy.java
        
        @Lstudy/ParmeterEx;()
        
        @Lstudy/ParmeterEx;() : CLASS_TYPE_PARAMETER 0, null
        
        // access flags 0x0
        Ljava/lang/String; name
        @Lstudy/ParmeterEx;() : FIELD, null
        
        // access flags 0x1
        public <init>()V
        L0
            LINENUMBER 4 L0
            ALOAD 0
            INVOKESPECIAL java/lang/Object.<init> ()V
        L1
            LINENUMBER 5 L1
            ALOAD 0
            LDC "default"
            PUTFIELD study/AnnotationStudy.name : Ljava/lang/String;
            RETURN
        L2
            LOCALVARIABLE this Lstudy/AnnotationStudy; L0 L2 0
            // signature Lstudy/AnnotationStudy<TT;>;
            // declaration: this extends study.AnnotationStudy<T>
            MAXSTACK = 2
            MAXLOCALS = 1
        
        // access flags 0x1
        // signature <R:Ljava/lang/Object;>(Ljava/lang/String;TR;)V
        // declaration: void print<R>(java.lang.String, R)
        public print(Ljava/lang/String;Ljava/lang/Object;)V
        @Lstudy/ParmeterEx;() : METHOD_TYPE_PARAMETER 0, null
        @Lstudy/ParmeterEx;() : METHOD_FORMAL_PARAMETER 0, null
        @Lstudy/ParmeterEx;() : METHOD_FORMAL_PARAMETER 1, null
        L0
            LINENUMBER 10 L0
            ICONST_1
            ISTORE 3
        L1
            LINENUMBER 11 L1
            RETURN
        L2
            LOCALVARIABLE this Lstudy/AnnotationStudy; L0 L2 0
            // signature Lstudy/AnnotationStudy<TT;>;
            // declaration: this extends study.AnnotationStudy<T>
            LOCALVARIABLE t Ljava/lang/String; L0 L2 1
            LOCALVARIABLE r Ljava/lang/Object; L0 L2 2
            // signature TR;
            // declaration: r extends R
            LOCALVARIABLE a I L1 L2 3
            LOCALVARIABLE @Lstudy/ParmeterEx;() : LOCAL_VARIABLE, null [ L1 - L2 - 3 ]
            MAXSTACK = 1
            MAXLOCALS = 4
        
        // access flags 0x9
        public static main([Ljava/lang/String;)V
        L0
            LINENUMBER 15 L0
            RETURN
        L1
            LOCALVARIABLE args [Ljava/lang/String; L0 L1 0
            MAXSTACK = 0
            MAXLOCALS = 1
        }

        ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด TYPE_USE๋ฅผ ์‚ฌ์šฉํ•ด๋„ ์ปดํŒŒ์ผ ๊ฒฐ๊ณผ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์ ์ ˆํ•œ ์–ด๋…ธํ…Œ์ด์…˜ TARGET์œผ๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

        @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE})
        @Retention(RetentionPolicy.CLASS)
        @Documented
        public @interface NonNull {
        }

        Lombok์˜ NonNull ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜๋„ Target๋ฒ”์œ„๊ฐ€ TYPE_USE๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋‹ค.

2. ์ค‘๋ณต ์‚ฌ์šฉ ๊ฐ€๋Šฅ

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
public @interface Chicken {
    String value() default "ํ›„๋ผ์ด๋“œ";
}

//error
@Chicken
@Chicken("์–‘๋…")
public class App() {

}

๊ธฐ์กด์—๋Š” ์œ„์™€ ๊ฐ™์ด ๊ฐ™์€ ์–ด๋…ธํ…Œ์ด์…˜์„ ๊ฐ™์€๋ฒ”์œ„์— ์ค‘๋ณตํ•ด์„œ ์ •์˜ํ•  ์ˆ˜ ์—†์—ˆ๋Š”๋ฐ java8๋ถ€ํ„ฐ๋Š” @Repeatable()์ด ์ถ”๊ฐ€๋˜์–ด ์ค‘๋ณตํ•ด์„œ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•ด์กŒ๋‹ค.

Reapetable์€ ํ•œ๊ฐœ์˜ value๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ ์—ฌ๊ธฐ์— ์ผ์ข…์˜ ์–ด๋…ธํ…Œ์ด์…˜ ์ปจํ…Œ์ด๋„ˆ ์—ญํ• ์„ ํ•  ์–ด๋…ธํ…Œ์ด์…˜ ํด๋ž˜์Šค๋ฅผ ๋„˜๊ฒจ์ฃผ๋ฉด ํ•ด๋‹น ์ปจํ…Œ์ด๋„ˆ์— ์ค‘๋ณต์‚ฌ์šฉํ•œ ์–ด๋…ธํ…Œ์ด์…˜๋“ค์„ ๋‹ด๋Š” ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•˜๊ฒŒ ๋œ๋‹ค. ์ด๋•Œ ์ฃผ์˜ํ•  ์ ์ด Reapeatable์˜ value๋Š” ์–ด๋…ธํ…Œ์ด์…˜์˜ ์ปจํ…Œ์ด๋„ˆ ์—ญํ• ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ค‘๋ณตํ•ด์„œ ์‚ฌ์šฉํ•  ์–ด๋…ธํ…Œ์ด์…˜๋ณด๋‹ค ์ƒ๋ช…์ฃผ๊ธฐ(RetentionPolicy)๊ฐ€ ๊ธธ์–ด์•ผ๋งŒ ํ•œ๋‹ค.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
public @interface ChickenContainer {
    Chicken[] value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
@Repeatable(ChickenContainer.class)
public @interface Chicken {
    String value() default "ํ›„๋ผ์ด๋“œ";
}

@Chicken("์–‘๋…")
@Chicken("๋งˆ๋Š˜๊ฐ„์žฅ")
public class App {

    public static void main(String[] args) {
        ChickenContainer chickenContainer = App.class.getAnnotation(ChickenContainer.class);
        Arrays.stream(chickenContainer.value()).forEach(c -> {
            System.out.println(c.value());
        });
    }
}

//print
์–‘๋…
๋งˆ๋Š˜๊ฐ„์žฅ

//bytecode
// class version 59.0 (59)
// access flags 0x21
public class javaStudy/Example {

  // compiled from: Example.java

  @LjavaStudy/ChickenContainer;(value={@LjavaStudy/Chicken;(value="\uc591\ub150"), @LjavaStudy/Chicken;(value="\ub9c8\ub298\uac04\uc7a5")})
  // access flags 0x19
  public final static INNERCLASS java/lang/invoke/MethodHandles$Lookup java/lang/invoke/MethodHandles Lookup

  // access flags 0x1
  public <init>()V
   L0
    LINENUMBER 7 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    RETURN
   L1
    LOCALVARIABLE this LjavaStudy/Example; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x9
  public static main([Ljava/lang/String;)V
   L0
    LINENUMBER 9 L0
    LDC LjavaStudy/Example;.class
    LDC LjavaStudy/ChickenContainer;.class
    INVOKEVIRTUAL java/lang/Class.getAnnotation (Ljava/lang/Class;)Ljava/lang/annotation/Annotation;
    CHECKCAST javaStudy/ChickenContainer
    ASTORE 1
   L1
    LINENUMBER 10 L1
    ALOAD 1
    INVOKEINTERFACE javaStudy/ChickenContainer.value ()[LjavaStudy/Chicken; (itf)
    INVOKESTATIC java/util/Arrays.stream ([Ljava/lang/Object;)Ljava/util/stream/Stream;
    INVOKEDYNAMIC accept()Ljava/util/function/Consumer; [
      // handle kind 0x6 : INVOKESTATIC
      java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
      // arguments:
      (Ljava/lang/Object;)V,
      // handle kind 0x6 : INVOKESTATIC
      javaStudy/Example.lambda$main$0(LjavaStudy/Chicken;)V,
      (LjavaStudy/Chicken;)V
    ]
    INVOKEINTERFACE java/util/stream/Stream.forEach (Ljava/util/function/Consumer;)V (itf)
   L2
    LINENUMBER 13 L2
    RETURN
   L3
    LOCALVARIABLE args [Ljava/lang/String; L0 L3 0
    LOCALVARIABLE chickenContainer LjavaStudy/ChickenContainer; L1 L3 1
    MAXSTACK = 2
    MAXLOCALS = 2

  // access flags 0x100A
  private static synthetic lambda$main$0(LjavaStudy/Chicken;)V
   L0
    LINENUMBER 11 L0
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    ALOAD 0
    INVOKEINTERFACE javaStudy/Chicken.value ()Ljava/lang/String; (itf)
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L1
    LINENUMBER 12 L1
    RETURN
   L2
    LOCALVARIABLE c LjavaStudy/Chicken; L0 L2 0
    MAXSTACK = 2
    MAXLOCALS = 1
}

ChickenConatiner ์–ด๋…ธํ…Œ์ด์…˜์„ ์ƒ์„ฑํ•˜์—ฌ Chicken ์–ด๋…ธํ…Œ์ด์…˜๋“ค์„ value๋กœ ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

MethodHandles$Lookup๋ผ๋Š” ์ด๋ฆ„์˜ ํด๋ž˜์Šค๋กœ innerClass๊ฐ€ ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด๋Š” ๋ฉ”์„œ๋“œ ํ•ธ๋“ค์„ ์ƒ์„ฑํ•˜๊ธฐ์œ„ํ•œ factory class๋กœ ChickenContainer์˜ value()์ธ Chicken[]์— ์ ‘๊ทผํ•˜๊ธฐ์œ„ํ•œ class



๋ฐฐ์—ด ๋ณ‘๋ ฌ ์ •๋ ฌ

Arrays.parallerSort()๊ฐ€ ์ถ”๊ฐ€๋˜์–ด ๋ถ„์‚ฐ๋˜์–ด ์ •๋ ฌ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

public class Example {
    public static void main(String[] args) {
        int size = 1500;
        int[] numbers = new int[size];
        Random random = new Random();

        IntStream.range(0,size).forEach(i -> numbers[i] = random.nextInt());
        long start = System.nanoTime();
        Arrays.sort(numbers);
        System.out.println("time : " + (System.nanoTime() - start) );

        IntStream.range(0,size).forEach(i -> numbers[i] = random.nextInt());
        start = System.nanoTime();
        Arrays.parallelSort(numbers);
        System.out.println("time : " + (System.nanoTime() - start) );
    }
}



Metaspace

JVM์˜ ์—ฌ๋Ÿฌ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ ์ค‘์— PermGen ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์ด ์—†์–ด์ง€๊ณ  Metaspace ์˜์—ญ์ด ์ƒ๊ฒผ๋‹ค.

PermGen

  • Heap ์˜์—ญ์— ์†ํ•จ
  • permanent generation, ํด๋ž˜์Šค ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๋Š” ๊ณณ.
  • ๊ธฐ๋ณธ ๊ฐ’์œผ๋กœ ๊ณ ์ •๋˜๊ณ  ์ œํ•œ๋œ ํฌ๊ธฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
  • PermGen์ดˆ๊ธฐ ์‚ฌ์ด์ฆˆ ์„ค์ • : -XX:PermSize=N
  • PermGen ์ตœ๋Œ€ ์‚ฌ์ด์ฆˆ ์„ค์ • : -XX:MaxOermSize=N
  • Old/Eden ์˜์—ญ๋ณด๋‹ค ์ ์€ ๋ฉ”๋ชจ๋ฆฌ์‚ฌ์ด์ฆˆ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ os bit, jdk ๋ฒ„์ „๋ณ„๋กœ ๋‹ค๋ฅด๋‹ค.
  • ๊ณ ์ •๋œ ํฌ๊ธฐ๋ฅผ ๊ฐ€์ง€๊ธฐ ๋•Œ๋ฌธ์— ํด๋ž˜์Šค๋ฅผ ๊ณ„์†ํ•ด์„œ ๋งŒ๋“ค๊ฒŒ ๋˜๋ฉด GC๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ •๋ฆฌํ•ด๋„ PermGen์‚ฌ์ด์ฆˆ๋ฅผ ๋„˜์–ด์„œ๋ฉด memory out ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

Metaspace

  • ํด๋ž˜์Šค ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๋Š” ๊ณณ
  • Heap์˜์—ญ์ด ์•„๋‹ˆ๋ผ Native ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์ด๋‹ค.
  • ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ œํ•œ๋œ ํฌ๊ธฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š๋‹ค. (๊ฒŒ์† ๋Š˜์–ด๋‚  ์ˆ˜ ์žˆ๋‹ค.)
    • ๊ณ„์†ํ•ด์„œ ๋Š˜์–ด๋‚  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž์นซ ์ž˜๋ชปํ•˜๋ฉด os์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋ชจ๋‘ ์žก์•„๋จน์–ด ์„œ๋ฒ„ ์ž์ฒด๊ฐ€ ๋‹ค์šด๋  ์ˆ˜ ์žˆ๋‹ค.
  • java8๋ถ€ํ„ฐ๋Š” PermGen ๊ด€๋ จ java์˜ต์…˜์€ ๋ฌด์‹œ
  • Metaspace ์ดˆ๊ธฐ ์‚ฌ์ด์ฆˆ ์„ค์ • : -XX:MetaspaceSize=N
  • Metaspace ์ตœ๋Œ€ ์‚ฌ์ด์ฆˆ ์„ค์ • : -XX:MaxMetaspaceSize=N



ํ›„๊ธฐ

์‹œ์ž‘ํ• ๋•Œ๋งŒํ•ด๋„ 5์ฃผ๊ฐ€ ๋˜๊ฒŒ ๊ธด ๊ฒƒ์ฒ˜๋Ÿผ ๋А๊ปด์กŒ๊ณ , Java8ํ•˜๋‚˜๋ฅผ ๋„ˆ๋ฌด ์˜ค๋ž˜๋„๋Š”๊ฒŒ ์•„๋‹Œ๊ฐ€ ์‹ถ์—ˆ๋Š”๋ฐ ๋ง‰์ƒ ์ง„ํ–‰ํ•ด๋ณด๋‹ˆ ๋ถ„๋Ÿ‰์ด ์ •๋ง ์ ์ ˆํ–ˆ์œผ๋ฉฐ ์˜คํžˆ๋ ค ์‹œ๊ฐ„์ด ๋ถ€์กฑํ•œ ๋А๋‚Œ์ด์—ˆ๋‹ค.

์–ด๋–ค ๊ธฐ๋Šฅ๋ถ€ํ„ฐ๊ฐ€ java8์˜ ๊ธฐ๋Šฅ์ธ์ง€ ๊ตฌ๋ถ„์ด ์•ˆ๊ฐ”๋Š”๋ฐ ์ด๋ฒˆ ๊ธฐํšŒ์— ํ™•์‹คํžˆ ์•Œ๊ฒŒ ๋˜์—ˆ๊ณ  ํŠนํžˆ ๋žŒ๋‹ค๋ถ€๋ถ„์€ ๋งŽ์ด ์‚ฌ์šฉํ•  ๊ฒƒ ๊ฐ™๋‹ค.

๋‹ค์Œ ์ฃผ์ œ๋Š” ๋””์ž์ธํŒจํ„ด์ธ๋ฐ ๊ธฐ๋Œ€๊ฐ€ ๋œ๋‹ค.