๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๊ฐœ์ธ ๊ณต๋ถ€/Java, Python

[Java] Reflection

by syLim___ 2023. 11. 17.
728x90

 

โœ…  Reflection์ด๋ž€?

 

 - Reflection์€ ํด๋ž˜์Šค ํ•„๋“œ, ๋ฉ”์„œ๋“œ์˜ ๊ตฌ์ฒด์ ์ธ ํƒ€์ž…์ด๋‚˜ ์ •๋ณด๋ฅผ ์•Œ์ง€ ๋ชปํ•˜๋”๋ผ๋„

    ํ•ด๋‹น ํด๋ž˜์Šค์˜ ํ•„๋“œ, ๋ฉ”์„œ๋“œ, ํƒ€์ž…๋“ค์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” Java api์ด๋‹ค.

 

 - ์ปดํŒŒ์ผํƒ€์ž„์ด ์•„๋‹ˆ๋ผ, ๋Ÿฐํƒ€์ž„์— ํŠน์ • ํด๋ž˜์Šค์˜ ์ •๋ณด๋ฅผ ๋™์ ์œผ๋กœ ์ถ”์ถœํ•œ๋‹ค.

 

 

๐Ÿฅ ์ด๋ฒˆ ํฌ์ŠคํŒ…์—๋Š” reflection์œผ๋กœ ํด๋ž˜์Šค ์ •๋ณด๋ฅผ ์–ด๋–ป๊ฒŒ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋Š”์ง€,

    reflection์„ ์‚ฌ์šฉํ•˜๋ฉด ์™œ ์ข‹์€์ง€ ์ •๋ฆฌํ•ด๋ณด๊ณ ์ž ํ•œ๋‹น

 


 

์šฐ์„  ์•„๋ž˜์™€ ๊ฐ™์ด User ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

 

์ด์ œ reflection์„ ํ†ตํ•ด User ํด๋ž˜์Šค ์™ธ๋ถ€์—์„œ User ํด๋ž˜์Šค์˜ ํ•„๋“œ, ๋ฉ”์„œ๋“œ๋“ค์„ ๊ฐ€์ ธ์™€์„œ ์‚ฌ์šฉํ•ด๋ณผ ๊ฒƒ์ด๋‹ค.

public class User {

    private String name;
    private int age;

    private User(){
        this.name = "guest";
        this.age = 0;
    }
    
    public User(int age){
        this.name = "guest";
        this.age = age;
    }
    
    public User(String name, int age){
        this.name = name;
        this.age = age;
    }
    
    public String getName(){
        return this.name;
    }
    
    public int getAge(){
        return this.age;
    }
    
    private void setName(String name){
        this.name = name;
    }

}

 

 

 

โœ… ํด๋ž˜์Šค ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ (3๊ฐ€์ง€ ๋ฐฉ๋ฒ•)

 

 - java.lang.Class ํด๋ž˜์Šค ์ด์šฉ

๐Ÿฅ java.lang.Class ํด๋ž˜์Šค
  - ์‹คํ–‰์ค‘์ธ ์ž๋ฐ” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํด๋ž˜์Šค์™€ ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํด๋ž˜์Šค์ด๋‹ค.
  - public constructor๊ฐ€ ๋”ฐ๋กœ ์—†๊ณ , JVM์ด Class object๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ด์ค€๋‹ค.

 

 

 1๏ธโƒฃ ํด๋ž˜์Šคํƒ€์ž….class ๋กœ ๊ฐ€์ ธ์˜ค๊ธฐ

Class userClass = User.class;

 

2๏ธโƒฃ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ํ›„, getClass ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๊ฐ€์ ธ์˜ค๊ธฐ

User user = new User("user", 20);
Class userClass = user.getClass();

 

3๏ธโƒฃ ์Šคํƒœํ‹ฑ ๋ฉ”์„œ๋“œ forName()์œผ๋กœ ๊ฐ€์ ธ์˜ค๊ธฐ

Class userClass = Class.forName("com.sy.reflection.User");

 

 

 

โœ… get ๋ฉ”์„œ๋“œ vs getDeclared ๋ฉ”์„œ๋“œ

 

ํด๋ž˜์Šค ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์™”์œผ๋ฉด,

java.lang.reflect ํŒจํ‚ค์ง€์˜ ํ•˜์œ„ ํด๋ž˜์Šค๋“ค์„ ์ด์šฉํ•ด์„œ ํ•„๋“œ์™€ ๋ฉ”์„œ๋“œ๋“ค์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์—ฌ๊ธฐ์—๋Š” get์œผ๋กœ ์‹œ์ž‘๋˜๋Š” ๋ฉ”์„œ๋“œ๋“ค๊ณผ getDeclared๋กœ ์‹œ์ž‘๋˜๋Š” ๋ฉ”์„œ๋“œ๋“ค์ด ์žˆ๋‹ค.

 

์šฐ์„  ๋‘˜์˜ ์ฐจ์ด์ ๋ถ€ํ„ฐ ์•Œ๊ณ  ์ฐจ๊ทผ์ฐจ๊ทผ ์‚ดํŽด๋ณด๋„๋ก ํ•˜์ž!

 

get___() ์ƒ์œ„ ํด๋ž˜์Šค์™€ ์ธํ„ฐํŽ˜์ด์Šค๋กœ๋ถ€ํ„ฐ ์ƒ์†๋ฐ›์€ ๋ฉ”์„œ๋“œ๋ฅผ ํฌํ•จํ•˜์—ฌ ๋ชจ๋“  public ์š”์†Œ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค.
getDeclared___() ์ƒ์œ„ ํด๋ž˜์Šค์™€ ์ธํ„ฐํŽ˜์ด์Šค๋กœ๋ถ€ํ„ฐ ์ƒ์†๋ฐ›์€ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ์™ธํ•˜๊ณ ,
ํ•ด๋‹น ํด๋ž˜์Šค์— ์ง์ ‘ ์ •์˜ํ•œ ๋ชจ๋“  ์š”์†Œ๋ฅผ ์ ‘๊ทผ์ œ์–ด์ž์— ๊ด€๊ณ„ ์—†์ด ๊ฐ€์ ธ์˜จ๋‹ค.
(private, protected, public ๋ชจ๋‘ ๊ฐ€์ ธ์˜จ๋‹ค๋Š” ๋œป์ด๋‹ค.)

 

 

 

โœ…  ์ƒ์„ฑ์ž ๊ฐ€์ ธ์˜ค๊ธฐ

 

 - java.lang.reflect.Constructor ํด๋ž˜์Šค ์ด์šฉ

 

 - getConstructor() ๋˜๋Š” getDeclaredConstructor()๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ์ž๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ ,

    newInstance ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 - ์ƒ์„ฑ์ž์— ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, ํŒŒ๋ผ๋ฏธํ„ฐ ํƒ€์ž…์„ ์ˆœ์„œ๋Œ€๋กœ ์ ์–ด์ฃผ๋ฉด ๋œ๋‹ค.

 

// ์ƒ์„ฑ์ž ๊ฐ€์ ธ์˜ค๊ธฐ
Constructor noArgsConstructor = userClass.getDeclaredConstructor();
noArgsConstructor.setAccessible(true); // IllegalAccessException ๋ฐฉ์ง€

Constructor oneArgConstructor = userClass.getDeclaredConstructor(int.class);
Constructor allArgsConstructor = userClass.getDeclaredConstructor(String.class, int.class);

// ์ธ์Šคํ„ด์Šค ์ƒ์„ฑํ•˜๊ธฐ (์ธ์Šคํ„ด์Šค๋Š” Object ํƒ€์ž…์œผ๋กœ ์ƒ์„ฑ๋œ๋‹ค.)
User user1 = (User) noArgsConstructor.newInstance();
User user2 = (User) oneArgConstructor.newInstance(30);
User user3 = (User) allArgsConstructor.newInstance("sy", 24);

 

์œ„์—์„œ ์ž‘์„ฑํ•œ User ํด๋ž˜์Šค๋ฅผ ๋ณด๋ฉด

์ฒซ๋ฒˆ์งธ ์ƒ์„ฑ์ž๋Š” private์œผ๋กœ ์ž‘์„ฑ๋˜์–ด ์žˆ๊ณ , ๋‚˜๋จธ์ง€ ์ƒ์„ฑ์ž๋“ค์€ public์œผ๋กœ ์ž‘์„ฑ๋˜์–ด ์žˆ๋‹ค.

 

์ƒ์„ฑ์ž๊ฐ€ private์œผ๋กœ ์ •์˜๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ์—๋Š”,

๋‘ ๋ฒˆ์งธ ๋ผ์ธ์ฒ˜๋Ÿผ setAccesible(true) ์„ค์ •์„ ๋ฏธ๋ฆฌ ํ•ด์ฃผ์–ด์•ผ

java.lang.IllegalAccessException์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค!!!

 

 

โœ… ํ•„๋“œ ๊ฐ€์ ธ์˜ค๊ธฐ

 

 - java.lang.reflect.Field ํด๋ž˜์Šค ์ด์šฉ

 

 - ์œ„์—์„œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ private ํ•„๋“œ์— ๋Œ€ํ•ด์„œ๋Š” setAccesible(true) ๋กœ ์„ค์ •์„ ํ•ด์ฃผ์–ด์•ผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

 - ์œ„์—์„œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํ•„๋“œ๋Š” Object ํƒ€์ž…์œผ๋กœ ๊ฐ€์ ธ์™€์ง€๊ธฐ ๋•Œ๋ฌธ์— ํƒ€์ž…์บ์ŠคํŒ…์„ ๋”ฐ๋กœ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

 - ํ•„๋“œ์˜ getter๊ฐ€ ๋”ฐ๋กœ ์ •์˜๋˜์–ด ์žˆ์ง€ ์•Š์•„๋„ get๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์ธ์Šคํ„ด์Šค์˜ ํ•„๋“œ value๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

 

User userSy = (User) allArgsConstructor.newInstance("sy", 24);

Field[] fields = userClass.getDeclaredFields();
for(Field field : fields){
        field.setAccessible(true);
        System.out.println("Field type=" + field.getType());
        System.out.println("Field name=" + field.getName());
        System.out.println("Field value=" + field.get(userSy)); // ์ธ์Šคํ„ด์Šค ์ด๋ฆ„
        System.out.println("--------");
}

/* 
output:
Field type=int
Field name=age
Field value=24
*/

 

 

 - ํ•„๋“œ์˜ setter๊ฐ€ ์ •์˜๋˜์–ด ์žˆ์ง€ ์•Š์•„๋„, set ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ธ์Šคํ„ด์Šค์˜ ํ•„๋“œ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Field nameField = userClass.getDeclaredField("name");
nameField.setAccessible(true);
nameField.set(userSy, "SYSY"); //  ์ธ์Šคํ„ด์Šค ์ด๋ฆ„, ํŒŒ๋ผ๋ฏธํ„ฐ

System.out.println(nameField.get(userSy)); // output: SYSY

 

 

 

โœ… ๋ฉ”์„œ๋“œ ๊ฐ€์ ธ์˜ค๊ธฐ

 

 - java.lang.reflect.Method ์ด์šฉ

 

 - ์œ„์—์„œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ private ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•ด์„œ๋Š” setAccesible(true) ๋กœ ์„ค์ •์„ ํ•ด์ฃผ์–ด์•ผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

 - ๋งŒ์•ฝ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ€์ง€๋Š” ๋ฉ”์„œ๋“œ๋ผ๋ฉด, ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ ํŒŒ๋ผ๋ฏธํ„ฐ ํƒ€์ž…์„ ์ˆœ์„œ๋Œ€๋กœ ์ ์–ด์ฃผ๋ฉด ๋œ๋‹ค.

 

 - invoke ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

// ๋ฉ”์„œ๋“œ ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ
Method[] methods = userClass.getDeclaredMethods();
for(Method method : methods){
    method.setAccessible(true);
    System.out.println(method);
}
/*
output:
private void com.sy.reflection.User.setName(java.lang.String)
public int com.sy.reflection.User.getAge()
*/

// invoke() ๋กœ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœํ•˜๊ธฐ
Method setUserName = userClass.getDeclaredMethod("setName", String.class); // ๋ฉ”์„œ๋“œ๋ช…, ํŒŒ๋ผ๋ฏธํ„ฐ ํƒ€์ž…
setUserName.setAccessible(true);
setUserName.invoke(userSy, "sy"); // ์ธ์Šคํ„ด์Šค๋ช…, ํŒŒ๋ผ๋ฏธํ„ฐ

System.out.println(nameField.get(userSy)); // output: sy

 

 

 

โœ…  References

 - https://hudi.blog/java-reflection/

 

 

728x90

'๊ฐœ์ธ ๊ณต๋ถ€ > Java, Python' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Java] String ํด๋ž˜์Šค  (0) 2024.07.02
[Java] ๋™์ผ์„ฑ, ๋™๋“ฑ์„ฑ  (0) 2024.06.26
[Java] equals(), hashCode()  (0) 2023.10.25
[Java] BlockingQueue  (0) 2023.10.18
[Java] Java TCP socket programming  (0) 2023.09.19