본 포스트는 카카오 테크 캠퍼스 1기에서 제공하는 패스트캠퍼스 강의에서 배운 내용을 토대로 정리하였습니다.

카카오 테크 캠퍼스

동적 로딩


  • 컴파일 시에 데이터 타입이 binding 되는 것이 아닌, 실행(runtime) 중에 데이터 타입을 binding 하는 방법

  • 프로그래밍 시에는 문자열 변수로 처리했다가 런타임시에 원하는 클래스를 로딩하여 binding 할 수 있다는 장점

  • 컴파일 시에 타입이 정해지지 않으므로 동적 로딩시 오류가 발생하면 프로그램의 심각한 장애가 발생가능

ex)

JDBC를 사용할떄 JDBC DB 라이브러리(Oracle,MySQL,MSSQL) 모두 Static하게 링크되어 컴파일이 되는 방식이 아닌, 라이브러리가 설치된 상태에서 필요시 호출이 된다.



Class 클래스 사용하기


  • 자바의 모든 클래스와 인터페이스는 컴파일 후 .class 파일이 생성됨

  • Class 클래스는 컴파일 된 class 파일을 로드하여 객체를 동적 로드하고, 정보를 가져오는 메서드가 제공됨

  1. Class.forName("클래스 이름") 메서드로 클래스를 동적으로 로드 함
Class c = Class.forName("java.lang.String");
  1. 클래스 이름으로 직접 Class 클래스 가져오기
Class c = String.class;
  1. 생성된 인스턴스에서 Class 클래스 가져오기
String s = new String();
Class c = s.getClass();  //Object 메서드
  • Class의 newInstance()메서드로 인스턴스 생성
    => new 키워드를 사용하지 않고 클래스 정보를 활용하여 인스턴스를 생성할 수 있음

예제

DynamicLoadingTest.java

public class DynamicLoadingTest {

	public static void main(String[] args) throws ClassNotFoundException {
        
		Class c3 =  Class.forName("java.lang.String");
		//Class.forName 메서드는 클래스 이름을 인수로 사용하고
        //해당 클래스의 Class 개체를 반환한다.
		Constructor<String>[] cons =  c3.getConstructors();
        // getConstructors() 메서드는 Class 개체에 대한 
        // 모든 생성자를 포함하는 Constructor[] 배열을 반환한다.
		for(Constructor con: cons) {
			System.out.println(con);
		}//String의 모든 생성자들이 출력될 것이다.
		
		System.out.println();
		
		Method[] methods = c3.getMethods();
        //getMethods() 메서드는 Class 개체에 대한 
        // 모든 메서드를 포함하는 Method[] 배열을 반환한다.
		for(Method  method : methods) {
			System.out.println(method);
		}//String의 모든 메서드들이 출력될 것이다.
	}

}

메서드 출력 결과 (너무 많아서 짤림)

생성자 출력 결과

reflection 프로그래밍


설명

  • Class 클래스를 사용하여 클래스의 정보(생성자, 변수, 메서드)등을 알 수 있고 인스턴스를 생성하고, 메서드를 호출하는 방식의 프로그래밍

  • 로컬 메모리에 객체가 없는 경우, 원격 프로그래밍, 객체의 타입을 알 수 없는 경우에 사용

  • java.lang.reflect 패키지에 있는 클래스를 활용하여 프로그래밍

  • 일반적으로 자료형을 알고 있는 경우엔 사용하지 않음

예제

Person.java (예제로 쓰일 객체)

public class Person {
	private String name;
	private int age;
	
	public Person() {};
	
	public Person(String name) {
		this.name = name;
	}
	
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
	
	public String toString() {
		return name;
	}
}

ClassTest.java

public class ClassTest {

	public static void main(String[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException,
						ClassNotFoundException, NoSuchMethodException, SecurityException {
        //1. 일반적인 객체 생성 방법
		Person person = new Person("James");
		System.out.println(person);
        //James가 출력된다.
        
        
        //2. Class 클래스를 이용한 방법
        
        //ch04패키지에 있는 Person이라는 클래스를 찾아서 
        //Class 자료형으로 반환
        Class personClass = Class.forName("ch04.Person");
        
        // String 클래스 찾아서 Class 자료형으로 반환
		Class parameterType = Class.forName("java.lang.String");
        
        //Class 클래스의 getConstructor() 메서드는 지정된 매개변수 유형 목록과 
        //일치하는 클래스의 생성자를 반환한다.
		Constructor cons = personClass.getConstructor(parameterType);
        
		Object initargs = "DIGIMON";
        //newInstance() 메서드는 해당 생성자로 인스턴스를
        //생성할떄 사용되고, 매개변수는 Object자료형으로 넣어주면 된다.
        //Object 자료형을 반환하기에, Person 자료형으로 명시적 형변환(다운캐스팅)을 한다.
        //Object 클래스는 모든 클래스의 최상위 클래스이다.
		Person personLee = (Person) cons.newInstance(initargs);
		System.out.println(personLee);
        //DIGIMON이 출력된다.

        
	}
}
profile
새로운 여정은 언제나 두렵고 동시에 흥미로 가득 차 있다.

0개의 댓글