์ค๋์ ํด๋์ค๋ฅผ ์์ฑํด๋ณด๋ ์์ ๋ฅผ ๊ฐ์ ธ์๋ดค์ต๋๋ค.
ํด๋์ค๋ฅผ ์์ฑํ ๋๋ ClassWriter ์ปดํฌ๋ํธ๋ง ํ์ํฉ๋๋ค.
์, ์๋์ ๊ฐ์ ์ธํฐํ์ด์ค๋ฅผ ClassWriter๋ฅผ ์ด์ฉํด์ ์์ฑํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
:: ์์ฑํ๋ ค๋ ์ธํฐํ์ด์ค
package BCItest;
public interface Comparable extends Mesurable {
int LESS = -1;
int EQUAL = 0;
int GREATER = 1;
int compareTo(Object o);
}
-- ์ ์ธํฐํ์ด์ค๋ฅผ ์์ฑํ๊ธฐ์ํ ์์ค
private byte[] writeClass(){
ClassWriter cw = new ClassWriter(0);
cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT + Opcodes.ACC_INTERFACE,
"BCItest/Comparable", null, "java/lang/Object",
new String[] { "BCItest/Mesurable" });
cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, "LESS", "I",
null, new Integer(-1)).visitEnd();
cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, "EQUAL", "I",
null, new Integer(0)).visitEnd();
cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC, "GREATER", "I",
null, new Integer(1)).visitEnd();
cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "compareTo",
"(Ljava/lang/Object;)I", null, null).visitEnd();
cw.visitEnd();
return cw.toByteArray();
}
๊ฐ ๋จํ๊ฒ ์์ค๋ฅผ ํ์ด๋ณผ๊น์?? ์ฐ์ ClassWriter ( ์ดํ cw ) ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ณ visit, visitField, visitMethod ๋ฉ์๋๋ฅผ ํธ์ถํ ๋ค์ ๋ง์ง๋ง์ผ๋ก visitEnd๋ฅผ ํธ์ถํ์ต๋๋ค. ๊ฐ ๋ฉ์๋์์ ๋ค์ด๊ฐ๋ ACC_XXX๋ผ๋ ์์๋ค์ ASM์ ๋ฏธ๋ฆฌ ์ ์๋์ด์๋ Opcodes ๋ค์ ๋๋ค. Opcodes ์ธํฐํ์ด์ค๋ฅผ ํตํด์ ์ฌ์ฉํ์ค ์ ์์ต๋๋ค.
ํ ๋ ์ ์ธ๋ถ๋ฅผ ๋ณด์๋ฉด ์ฒซ๋ฒ์งธ ํ๋๊ฐ int LESS ๋ผ๋ ํ๋์ฃ . ์ฐ์ ์ธํฐํ์ด์ค ๋ด์ ์ ์ธ๋์ด์๋ int๋ผ์ visitField๋ฉ์๋์์ public, final, static์ด๋ผ๋ ์์๊ฐ์ ์ฃผ๊ณ ๊ทธ ๋ค์์ ํ๋๋ช (LESS)๊ณผ ํ๋ ํ์ (I)์ ์ฃผ์์ต๋๋ค. ๊ทธ ๋ค์์ null์ generic๊ด๋ จ ํ๋์ ๋๋ค. ๋ง์ง๋ง์ผ๋ก๋ ํด๋น ํ๋์ ํ ๋นํ ๊ฐ์ ๋๋ค. ์ ์์ ์์๋ new Integer(-1)์ด์ฃ .
๊ทธ๋ฆฌ๊ณ cw๋ฅผ ๋ฐ์ดํธํํ๋ก ์ถ์ถํ์ต๋๋ค.
์ด์ ์ด ๋ฐ์ดํธ ํด๋์ค๋ฅผ ์ด์ฉํด์ ์์ฑ๋ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํด๋ณผ๊น์??
์ฐ์ ํด๋์ค๋ก๋๊ฐ ํ์ํฉ๋๋ค.
์๋์ ๊ฐ์ด MyClassLoader ํด๋์ค๋ฅผ ํ๋ ๋ง๋ค์ด์ฃผ์ธ์.
class MyClassLoader extends ClassLoader {
public Class defineClass(String name, byte[] b) {
return defineClass(name, b, 0, b.length);
}
}
๊ทธ๋ฆฌ๊ณ ์๋์ฒ๋ผ ํ ์คํธํด๋ณด๋ฉด ๋ฉ๋๋ค.
Class c = new MyClassLoader().defineClass("BCItest.Comparable", writeClass());
System.out.println(c.getName());
๋ฌธ์ ๊ฐ ์๋ค๋ฉด BCItest.Comparable ์ด๋ผ๊ณ ์ฝ์์ฐฝ์ ์ถ๋ ฅ์ด ๋ ๊ฒ๋๋ค.
์ฌ
๊ธฐ์ ์ ๊น!!! ์ ๊ฐ ์ค์ตํด๋ณธ ๊ฒฐ๊ณผ ์ธํฐํ์ด์ค๊ฐ Mesurable์ ์์ํ๋ ํํ๋ก ๋์ด์๊ธฐ ๋๋ฌธ์ Measurableํด๋์ค๊ฐ
์๋ค๋ฉด ์ค๋ฅ๊ฐ ๋ฉ๋๋ค. ๊ทธ๋์ 1. Measurable์ ์์ฑํด ์ฃผ์๊ฑฐ๋ ์๋๋ฉด 2. writeClass()์ cw.visit()
๋ฉ์๋์ ๋ง์ง๋ง ์ธ์์ธ new String[] { " .... "} ๋ฅผ null ๋ก ๋ฐ๊ฟ์ฃผ์๋ฉด ์คํ์ด ์ ๋ ๊ฒ๋๋ค.
๊ทธ๋ผ ๋ค์ ์๊ฐ์๋ ํด๋์ค ๋ณํ์ ๋ํด์ ์ฌ๋ฆฌ๋๋ก ํ๊ฒ ์ต๋๋ค.
์ถ์ฒ : ASM ๊ฐ์ด๋