package com.example;
public class DynamicData {
public void sayHello() {
System.out.println("안녕하세요!");
}
public void goodBye() {
System.out.println("안녕히계세요!");
}
}
package com.example;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
public class DynamicDataClassMain {
public static void main(String[] args) throws IOException, InstantiationException,
IllegalAccessException, ClassNotFoundException {
System.out.println("다운로드중 ...");
// 웹 서버에 존재하는 파일에 연결된 스트림을 생성하는 방법
URL url = new URL("http://www.jabook.org/DynamicData.class");
InputStream is = url.openStream();
// 스트림을 통해 읽은 데이터를 저장하기 위해 파일 출력 스트림 생성
FileOutputStream fos = new FileOutputStream("DynamicData.class");
int i;
// 입력 & 출력 스트림이 생성되었을 시 반복
while ( (i = is.read()) != -1) {
fos.write(i);
System.out.println("|");
}
// 열어놨던 입출력 스트림들은 반드시 닫아줘야 함
fos.close();
is.close();
System.out.println("\n 다운로드 완료 ...");
// 클래스의 이름 자체를 컴파일 타임에 사용할 수 없기 떄문에 문자열 형태로 클래스의 이름을 사용
// Class.forName(String str)이 호출되는 그 순간 클래스를 로딩하겠다는 의미
// 매개변수가 String 형인 이유 : 해당 클래스가 컴파일시 없기 때문
Class c = Class.forName("DynamicData");
// 동적으로 생성된 Class 정보를 이용해서 객체 생성
Object obj = c.newInstance();
System.out.println(obj);
/*
* 정적 바인딩과 동적 바인딩의 차이
* - 다운 캐스팅의 유무 (동적 바인딩 : X, 정적 바인딩 : O)
* - 이유 : 동적 바인딩은 컴파일시 해당 클래스의 이름을 사용할 수 없기 때문임
* (매개변수로 클래스 이름을 넣는게 아니라 위치만 넣으니까)
* 동적 바인딩은 멤버 메소드를 호출할 수 없다
*
* (중요) => 이 때, java.lang.Reflection 패키지의 Class 클래스를 이용하여
* 다운캐스팅 할 수 없는 객체여도 모든 작업을 할 수 있게 지원해줌 (ex. getContstructors())
*/
}
}