반응형

참고 코드

public class Book2 {
    public static String A = "A";

    private String B = "B";

    public Book2() {
    }

    public Book2(String b) {
        B = b;
    }

    private void c() {
        System.out.println("C");
    }

    public int sum(int left, int right) {
        return left + right;
    }

}

 

기본 생성자 생성

  • Class<T> 타입의 객체로 부터 인스턴스를 생성할 수 있다.
  • Constructor 를 사용하여 인스턴스를 생성하는 것이 권장되는 방법이다.
public class App2 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //클래스가 속한 패키지명을 모두 포함한 이름(FQCN, Fully Qualified Class Name)을 가지고 class 타입의 인스턴스를 가지고 오는 방법
        Class<?> bookClass = Class.forName("me.devhistory.Book2");
        Constructor<?> constructor = bookClass.getConstructor(null);
        Book2 book2 = (Book2) constructor.newInstance();
        System.out.println(book2);     //me.devhistory.Book2@1d251891
    }
}

 

파라미터를 가지는 생성자 생성

  • 생성자가 받는 파라미터를 Constructor 를 얻어올 때 인자로 전달한다. bookClass.getConstructor(String.class)
Class<?> bookClass = Class.forName("me.devhistory.Book2");
Constructor<?> constructor = bookClass.getConstructor(String.class);
Book2 book2 = (Book2) constructor.newInstance("Book2");
System.out.println(book2);     //me.devhistory.Book2@48140564

 

Static 필드 값 조작

  • Field 를 얻어와서 get, set 메소드를 통해 값을 얻어오거나 수정할 수 있다.
  • Static 선언된 Field 는 인스턴스를 생성하지 않고도 값을 얻어올 수 있다.
    • 메소드 영역에 메모리 저장
  • Static 선언된 Field는 인스턴스에 속해있지 않기 때문에 get, set 메소드의 Object 인자는 null을 입력한다.
Field a = Book2.class.getDeclaredField("A");
System.out.println(a.get(null));     //A
a.set(null, "AAA");
System.out.println(a.get(null));     //AAA

 

Non-Static 필드 값 조작

  • Field 를 얻어와서 get, set 메소드를 통해 값을 얻어오거나 수정할 수 있다.
  • 인스턴스에 속하는 Field 이기 때문에 인스턴스 생성해야 값을 얻어올 수 있다.
  • 접근 지시자가 private 타입인 경우, setAccessible(true)를 설정해준다.
  • get, set 메소드의 Object 인자로 인스턴스를 입력한다.
Class<?> bookClass = Class.forName("me.devhistory.Book2");
Constructor<?> constructor = bookClass.getConstructor(String.class);
Book2 book2 = (Book2) constructor.newInstance("Book2");

Field b = Book2.class.getDeclaredField("B");
b.setAccessible(true);
System.out.println(b.get(book2));   //B
b.set(book2, "BBB");
System.out.println(b.get(book2));   //BBB

 

메소드 조작

  • invoke 메소드를 통해 메소드를 실행할 수 있다.
  • 접근 지시자가 private 타입인 경우, setAccessible(true)를 설정해준다.
  • 메소드가 Static 선언이 되어있으면 invoke 메소드의 Object 인자는 null 설정한다.
  • 메소드가 Non-Static이면 invoke 메소드의 Object 인자로 인스턴스를 입력한다. 메소드에서 입력받는 파라미터가 존재한다면 추가적으로 파라미터 타입도 전달해야한다.
Class<?> bookClass = Class.forName("me.devhistory.Book2");
Constructor<?> constructor = bookClass.getConstructor(String.class);
Book2 book2 = (Book2) constructor.newInstance("Book2");

Method c = Book2.class.getDeclaredMethod("c");
c.setAccessible(true);
c.invoke(book2);   //C
  • 파라미터가 존재하는 메소드의 경우, 파라미터가 존재하는 생성자를 생성할 때와 유사하게 메소드가 받는 파라미터를 전달해주어야 한다.
Method d = Book2.class.getDeclaredMethod("sum", int.class, int.class);
int invoke = (int) d.invoke(book2, 1, 2);
System.out.println(invoke);   //3

[참고자료]

더 자바, 코드를 조작하는 다양한 방법, 백기선

반응형

+ Recent posts