๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
์–ธ์–ด/Java

[Java] 12. java.base ๋ชจ๋“ˆ (6) - 11, 12

by ์ ผ์ ผ39 2025. 7. 25.

12.11 ๋ฆฌํ”Œ๋ ‰์…˜

    - ์ž๋ฐ”๋Š” ํด๋ž˜์Šค์™€ ์ธํ„ฐํŽ˜์ด์Šค์˜ ๋ฉ”ํƒ€ ์ •๋ณด(ํŒจํ‚ค์ง€ ์ •๋ณด, ํƒ€์ž… ์ •๋ณด, ๋ฉค๋ฒ„ ์ •๋ณด ๋“ฑ)๋ฅผ Class ๊ฐ์ฒด๋กœ ๊ด€๋ฆฌํ•จ

    -> ๋ฆฌํ”Œ๋ ‰์…˜(reflection) : ์ด๋Ÿฌํ•œ ๋ฉ”ํƒ€ ์ •๋ณด๋ฅผ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์ฝ๊ณ  ์ˆ˜์ •ํ•˜๋Š” ํ–‰์œ„

    * ํ”„๋กœ๊ทธ๋žจ์—์„œ Class ๊ฐ์ฒด๋ฅผ ์–ป๋Š” ๋ฐฉ๋ฒ• - ์…‹ ์ค‘ ์–ด๋А ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ ๋™์ผํ•œ Class ๊ฐ์ฒด ์–ป์Œ
        1) Class clazz = ํด๋ž˜์Šค์ด๋ฆ„.class;                                    //ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ์–ป๊ธฐ 1
        2) Class clazz = Class.forName("ํŒจํ‚ค์ง€...ํด๋ž˜์Šค์ด๋ฆ„"); //ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ์–ป๊ธฐ 2
        3) Class clazz = ๊ฐ์ฒด์ฐธ์กฐ๋ณ€์ˆ˜.getClass();                        //๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ ์–ป๊ธฐ

1. ํŒจํ‚ค์ง€์™€ ํƒ€์ž… ์ •๋ณด ์–ป๊ธฐ

    - ํŒจํ‚ค์ง€์™€ ํƒ€์ž… (ํด๋ž˜์Šค, ์ธํ„ฐํŽ˜์ด์Šค) ์ด๋ฆ„ ์ •๋ณด๋ฅผ ์–ป๊ธฐ ์œ„ํ•œ ๋ฉ”์†Œ๋“œ

๋ฉ”์†Œ๋“œ ์šฉ๋„
Package getPackage() ํŒจํ‚ค์ง€ ์ •๋ณด ์ฝ๊ธฐ
String getSimpleName() ํŒจํ‚ค์ง€๋ฅผ ์ œ์™ธํ•œ ํƒ€์ž… ์ด๋ฆ„
String getName() ํŒจํ‚ค์ง€๋ฅผ ํฌํ•จํ•œ ์ „์ฒด ํƒ€์ž… ์ด๋ฆ„

2. ๋ฉค๋ฒ„ ์ •๋ณด ์–ป๊ธฐ

    - ํƒ€์ž…(ํด๋ž˜์Šค, ์ธํ„ฐํŽ˜์ด์Šค)๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ฉค๋ฒ„ ์ •๋ณด๋ฅผ ์–ป๋Š” ๋ฉ”์†Œ๋“œ (๋ชจ๋‘ java.lang.reflect ํŒจํ‚ค์ง€์— ์กด์žฌ)

๋ฉ”์†Œ๋“œ ์šฉ๋„
Constructor[ ] getDeclaredConstructors() ์ƒ์„ฑ์ž ์ •๋ณด ์ฝ๊ธฐ
Field[ ] getDeclaredFields() ํ•„๋“œ ์ •๋ณด ์ฝ๊ธฐ
Method[ ] getDeclaredMethods() ๋ฉ”์†Œ๋“œ ์ •๋ณด ์ฝ๊ธฐ

3. ๋ฆฌ์†Œ์Šค ๊ฒฝ๋กœ ์–ป๊ธฐ

    - Class ๊ฐ์ฒด๋Š” ํด๋ž˜์Šค ํŒŒ์ผ(~.class)์˜ ๊ฒฝ๋กœ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Œ
        -> ์ด ๊ฒฝ๋กœ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ƒ๋Œ€ ๊ฒฝ๋กœ์— ์žˆ๋Š” ๋‹ค๋ฅธ ๋ฆฌ์†Œ์Šค ํŒŒ์ผ์˜ ์ •๋ณด ์–ป์„ ์ˆ˜ ์žˆ์Œ

๋ฉ”์†Œ๋“œ ์šฉ๋„
URL getResource(String name) ๋ฆฌ์†Œ์Šค ํŒŒ์ผ์˜ URL ๋ฆฌํ„ด (๊ฒฝ๋กœ ์ •๋ณด๊ฐ€ ๋‹ด๊ธด URL ๊ฐ์ฒด ๋ฆฌํ„ด)
InputStream getResourceAsStream(String name) ๋ฆฌ์†Œ์Šค ํŒŒ์ผ์˜ InputStream ๋ฆฌํ„ด (ํŒŒ์ผ์˜ ๋‚ด์šฉ์„ ์ฝ์„ ์ˆ˜ ์žˆ๋„๋ก)
String photo1Path = clazz.getResource("photo1.jpg").getPath();
//C:\...\bin\photo1.jpg

    - getPath() : URL ๊ฐ์ฒด์˜ ๋ฉ”์†Œ๋“œ๋กœ ์ ˆ๋Œ€ ๊ฒฝ๋กœ๋ฅผ ๋ฆฌํ„ดํ•จ

 

12.12 ์–ด๋…ธํ…Œ์ด์…˜

    - ์–ด๋…ธํ…Œ์ด์…˜ : ์ฝ”๋“œ์—์„œ @๋กœ ์ž‘์„ฑ๋˜๋Š” ์š”์†Œ
                        - ํด๋ž˜์Šค ๋˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ปดํŒŒ์ผํ•˜๊ฑฐ๋‚˜ ์‹คํ–‰ํ•  ๋•Œ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ๊ฒƒ์ธ์ง€๋ฅผ ์•Œ๋ ค์ฃผ๋Š” ์„ค์ • ์ •๋ณด

    1) ์ปดํŒŒ์ผ ์‹œ ์‚ฌ์šฉํ•˜๋Š” ์ •๋ณด ์ „๋‹ฌ (์˜ˆ: @Override - ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋ฉ”์†Œ๋“œ ์žฌ์ •์˜ ๊ฒ€์‚ฌ๋ฅผ ํ•˜๋„๋ก ์„ค์ •ํ•จ)
    2) ๋นŒ๋“œ ํˆด์ด ์ฝ”๋“œ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์ •๋ณด ์ „๋‹ฌ
    3) ์‹คํ–‰ ์‹œ ํŠน์ • ๊ธฐ๋Šฅ์„ ์ฒ˜๋ฆฌํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์ •๋ณด ์ „๋‹ฌ

1. ์–ด๋…ธํ…Œ์ด์…˜ ํƒ€์ž… ์ •์˜์™€ ์ ์šฉ

    - ์–ด๋…ธํ…Œ์ด์…˜๋„ ํ•˜๋‚˜์˜ ํƒ€์ž…์ž„ -> ์–ด๋…ธํ…Œ์ด์…˜ ์‚ฌ์šฉ์„ ์œ„ํ•ด์„œ๋Š” ๋จผ์ € ์ •์˜๋ถ€ํ„ฐ ํ•ด์•ผ ํ•จ
       (์ธํ„ฐํŽ˜์ด์Šค ์ •์˜์™€ ์œ ์‚ฌํ•จ - @interface  ๋’ค์— ์‚ฌ์šฉํ•  ์–ด๋…ธํ…Œ์ด์…˜ ์ด๋ฆ„์ด ์˜จ๋‹ค)

public @interface AnnotationName {

}
@AnnotationName

    - ์–ด๋…ธํ…Œ์ด์…˜์€ ์†์„ฑ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Œ : ํƒ€์ž…, ์ด๋ฆ„์œผ๋กœ ๊ตฌ์„ฑ, ์ด๋ฆ„ ๋’ค์— ๊ด„ํ˜ธ ๋ถ™์ž„

public @interface AnnotationName {
    String prop1();
    int prop2() default 1;
}
@AnnotationName(prop1 = "๊ฐ’");
@AnnotationName(prop1 = "๊ฐ’", prop2 = 3);

    - ์–ด๋…ธํ…Œ์ด์…˜์€ ๊ธฐ๋ณธ ์†์„ฑ์ธ value๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Œ
    - ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•  ๋•Œ์—๋Š” ๊ฐ’๋งŒ ๊ธฐ์ˆ , ๊ทธ๋Ÿฌ๋ฉด value ์†์„ฑ์— ์ž๋™์œผ๋กœ ๋Œ€์ž…๋จ
    - ํ•˜์ง€๋งŒ value ์†์„ฑ๊ณผ ๋‹ค๋ฅธ ์†์„ฑ์˜ ๊ฐ’์„ ๋™์‹œ์— ์ฃผ๊ณ ์ž ํ•  ๋•Œ์—๋Š” ์†์„ฑ ์ด๋ฆ„์„ ๋ฐ˜๋“œ์‹œ ๋ช…์‹œ

public @interface AnnotationName {
    String value();
    int prop2() default 1;
}
@AnnotationName("๊ฐ’");
@AnnotationName(value = "๊ฐ’", prop2 = 3);

 

2. ์–ด๋…ธํ…Œ์ด์…˜ ์ ์šฉ ๋Œ€์ƒ

    - ElementType ์—ด๊ฑฐ ์ƒ์ˆ˜๋กœ ์ •์˜๋œ, ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋Œ€์ƒ์˜ ์ข…๋ฅ˜ (์–ด๋–ค ๋Œ€์ƒ-ํด๋ž˜์Šค/๋ฉ”์†Œ๋“œ ๋“ฑ-์— ์„ค์ • ์ •๋ณด๋ฅผ ์ ์šฉํ•  ๊ฒƒ์ธ์ง€)

ElementType ์—ด๊ฑฐ ์ƒ์ˆ˜ ์ ์šฉ ์š”์†Œ
TYPE ํด๋ž˜์Šค, ์ธํ„ฐํŽ˜์ด์Šค, ์—ด๊ฑฐ ํƒ€์ž…
ANNOTATION_TYPE ์–ด๋…ธํ…Œ์ด์…˜
FIELD ํ•„๋“œ
CONSTRUCTOR ์ƒ์„ฑ์ž
METHOD ๋ฉ”์†Œ๋“œ
LOCAL_VARIABLE ๋กœ์ปฌ ๋ณ€์ˆ˜
PACKAGE ํŒจํ‚ค์ง€

    - @Target ์–ด๋…ธํ…Œ์ด์…˜ : ์ ์šฉ ๋Œ€์ƒ์„ ์ง€์ •ํ•  ๋•Œ ์‚ฌ์šฉ
        - ๊ธฐ๋ณธ ์†์„ฑ value๋Š” ElementType ๋ฐฐ์—ด์„ ๊ฐ’์œผ๋กœ ๊ฐ€์ง : ์ ์šฉ ๋Œ€์ƒ์„ ๋ณต์ˆ˜ ๊ฐœ๋กœ ์ง€์ •ํ•˜๊ธฐ ์œ„ํ•ด!

@Target ( {ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
//ํด๋ž˜์Šค, ํ•„๋“œ, ๋ฉ”์†Œ๋“œ์— ์ ์šฉ ๊ฐ€๋Šฅ
//์ƒ์„ฑ์ž์—๋Š” ์ ์šฉ ๋ถˆ๊ฐ€๋Šฅ - @Target์— CONSTRUCTOR๊ฐ€ ์—†์œผ๋ฏ€๋กœ!
public @interface AnnotationName {
}
@AnnotationName //ํด๋ž˜์Šค์— ์ ์šฉ
public class ClassName {
    @AnnotationName //ํ•„๋“œ์— ์ ์šฉ
    private String fieldName;
    
    //@AnnotationName - ๋ถˆ๊ฐ€๋Šฅ
    public ClassName() {}
    
    @AnnotationName //๋ฉ”์†Œ๋“œ์— ์ ์šฉ
    public void methodName() {}
}

3. ์–ด๋…ธํ…Œ์ด์…˜ ์œ ์ง€ ์ •์ฑ…

    - @AnnotationName์„ ์–ธ์ œ๊นŒ์ง€ ์œ ์ง€ํ•  ๊ฒƒ์ธ๊ฐ€
    - @Retention ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด ์œ ์ง€ ์ •์ฑ…์„ ์ง€์ •ํ•จ
        - ๊ธฐ๋ณธ ์†์„ฑ์ธ value๋Š” RetentionPolicy ์—ด๊ฑฐ ์ƒ์ˆ˜ ๊ฐ’์„ ๊ฐ€์ง

RetentionPolicy ์—ด๊ฑฐ ์ƒ์ˆ˜ ์–ด๋…ธํ…Œ์ด์…˜ ์ ์šฉ ์‹œ์  ์–ด๋…ธํ…Œ์ด์…˜ ์ œ๊ฑฐ ์‹œ์ 
SOURCE ์ปดํŒŒ์ผํ•  ๋•Œ ์ ์šฉ ์ปดํŒŒ์ผํ•œ ํ›„์— ์ œ๊ฑฐ๋จ
CLASS ๋ฉ”๋ชจ๋ฆฌ๋กœ ๋กœ๋”ฉํ•  ๋•Œ ์ ์šฉ ๋ฉ”๋ชจ๋ฆฌ๋กœ ๋กœ๋”ฉ๋œ ํ›„์— ์ œ๊ฑฐ๋จ
RUNTIME ์‹คํ–‰ํ•  ๋•Œ ์ ์šฉ ๊ณ„์† ์œ ์ง€๋จ
@Target ( {ElementType.TYPE, ElementType.FIELD, ElementType.METHOD} )
@Retention ( RetentionPolicy.RUNTIME )
public @interface AnnotationName {
}

4. ์–ด๋…ธํ…Œ์ด์…˜ ์„ค์ • ์ •๋ณด ์ด์šฉ

    - ์–ด๋…ธํ…Œ์ด์…˜์€ ์•„๋ฌด๋Ÿฐ ๋™์ž‘์„ ๊ฐ€์ง€์ง€ ์•Š๋Š” ์„ค์ • ์ •๋ณด์ผ ๋ฟ์ž„
        -> ์ด ์„ค์ • ์ •๋ณด๋ฅผ ์ด์šฉํ•ด ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•  ๊ฒƒ์ธ์ง€๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ชซ์ž„!

    - ๋ฆฌํ”Œ๋ ‰์…˜์„ ์ด์šฉํ•ด ์ ์šฉ ๋Œ€์ƒ์œผ๋กœ๋ถ€ํ„ฐ ์–ด๋…ธํ…Œ์ด์…˜์˜ ์ •๋ณด๋ฅผ ์–ป์–ด๋‚ด๋Š” ๋ฉ”์†Œ๋“œ๋“ค

๋ฆฌํ„ด ํƒ€์ž… ๋ฉ”์†Œ๋“œ๋ช…(๋งค๊ฐœ๋ณ€์ˆ˜) ์„ค๋ช…
boolean isAnnotationPresent(AnnotationName.class) ์ง€์ •ํ•œ ์–ด๋…ธํ…Œ์ด์…˜์ด ์ ์šฉ๋˜์—ˆ๋Š”์ง€ ์—ฌ๋ถ€
Annotation getAnnotation(AnnotationName.class) ์ง€์ •ํ•œ ์–ด๋…ธํ…Œ์ด์…˜์ด ์ ์šฉ๋˜์–ด ์žˆ์Œ -> ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ฆฌํ„ด
๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด -> null ์„ ๋ฆฌํ„ด
Annotation[ ] getDeclaredAnnotations( ) ์ ์šฉ๋œ ๋ชจ๋“  ์–ด๋…ธํ…Œ์ด์…˜์„ ๋ฆฌํ„ด

    - ์ ์šฉ ๋Œ€์ƒ์„ METHOD, ์œ ์ง€ ์ •์ฑ…์„ RUNTIME์œผ๋กœ ํ•˜๊ณ , ๊ตฌ๋ถ„์„ ์— ๋Œ€ํ•œ ์„ค์ • ์ •๋ณด๋ฅผ ์†์„ฑ์œผ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” @PrintAnnotation

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target( {ElementType.METHOD} )
@Retention(RetentionPolicy.RUNTIME)
public @interface PrintAnnotation {
    String value() default "-"; //์„ ์˜ ์ข…๋ฅ˜
    int number() default 15;    //์ถœ๋ ฅ ํšŸ์ˆ˜
}
public class Service {
    @PrintAnnotation
    public void method1() {
        System.out.println("์‹คํ–‰ ๋‚ด์šฉ 1");
    }
    
    @PrintAnnotation("*")
    public void method2() {
        System.out.println("์‹คํ–‰ ๋‚ด์šฉ 2");
    }
    
    @PrintAnnotation(value="#", number=20)
    public void method3() {
        System.out.println("์‹คํ–‰ ๋‚ด์šฉ 3");
    }
}

    - ์‹คํ–‰ ํด๋ž˜์Šค์ธ PrintAnnotationExample์—์„œ๋Š” Service ํด๋ž˜์Šค์— ์„ ์–ธ๋œ ๋ฉ”์†Œ๋“œ๋ฅผ ๋ฆฌํ”Œ๋ ‰์…˜ํ•ด์„œ @PrintAnnotation์˜ ์„ค์ • ์ •๋ณด๋ฅผ ์–ป์–ด๋‚ธ ํ›„, ๊ตฌ๋ถ„์„ ์„ ์ถœ๋ ฅํ•˜๊ณ  ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœ์‹œํ‚ด

import java.lang.reflect.Method;

public class PrintAnnotationExample {
    public static void main(String[] args) throws Exception {
        Method[] declaredMethods = Service.class.getDeclaredMethods();
        for(Method method : declaredMethods) {
            //PrintAnnotation ์–ป๊ธฐ
            PrintAnnotation printAnnotation = method.getAnnotation(PrintAnnotation.class);
            
            //์„ค์ • ์ •๋ณด๋ฅผ ์ด์šฉํ•ด์„œ ์„  ์ถœ๋ ฅ
            printLine(PrintAnnotation);
            
            //๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ
            method.invoke(new Service());
            
            //์„ค์ • ์ •๋ณด๋ฅผ ์ด์šฉํ•ด์„œ ์„  ์ถœ๋ ฅ
            printLine(printAnnotation);
        }
    }
    
    public static void printLine(PrintAnnotation printAnnotation) {
        if(printAnnotation != null) {
            //number ์†์„ฑ๊ฐ’ ์–ป๊ธฐ
            int number = printAnnotation.number();
            for(int i = 0; i<number; i++) {
                //value ์†์„ฑ๊ฐ’ ์–ป๊ธฐ
                String value = printAnnotation.value();
                System.out.print(value);
            }
            System.out.println();
        }
    }
}
---------------
์‹คํ–‰ ๋‚ด์šฉ 1
---------------
###############
์‹คํ–‰ ๋‚ด์šฉ 3
###############
***************
์‹คํ–‰ ๋‚ด์šฉ 2
***************

    - Service.class.getDeclaredMethods()๋กœ ๊ฐ€์ ธ์˜จ ๋ฉ”์†Œ๋“œ ์ˆœ์„œ ๋•Œ๋ฌธ์— ์‹คํ–‰๋‚ด์šฉ 1, 3, 2 ์ด๋ ‡๊ฒŒ ๋‚˜์˜ด

'์–ธ์–ด > Java' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Java] 13. ์ œ๋„ค๋ฆญ (2) - 3~5  (0) 2025.08.04
[Java] 13. ์ œ๋„ค๋ฆญ (1) - 1, 2  (0) 2025.07.30
[Java] 12. java.base ๋ชจ๋“ˆ (5) - 9, 10  (1) 2025.07.25
[Java] 12. java.base ๋ชจ๋“ˆ (4) - 7, 8  (0) 2025.07.24
[Java] 12. java.base ๋ชจ๋“ˆ (3) - 4~6  (2) 2025.07.22