โ 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/
'๊ฐ์ธ ๊ณต๋ถ > 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 |