Java 클래스를 프로그래밍 방식으로 컴파일하고 인스턴스화하는 방법은 무엇입니까?
이 질문에 이미 답변이 있습니다.
속성 파일에 클래스 이름이 저장되어 있습니다. 클래스 저장소가 IDynamicLoad를 구현한다는 것을 알고 있습니다. 클래스를 동적으로 인스턴스화하는 방법은 무엇입니까?
지금 나는
Properties foo = new Properties();
foo.load(new FileInputStream(new File("ClassName.properties")));
String class_name = foo.getProperty("class","DefaultClass");
//IDynamicLoad newClass = Class.forName(class_name).newInstance();
newInstance는 컴파일 된 .class 파일 만로드합니까? 컴파일되지 않은 Java 클래스를 어떻게로드합니까?
컴파일되지 않은 Java 클래스를 어떻게로드합니까?
먼저 컴파일해야합니다. 이것은 javax.toolsAPI를 사용하여 프로그래밍 방식으로 수행 할 수 있습니다 . 이를 위해서는 JRE 위에있는 로컬 시스템에 JDK 만 설치하면됩니다.
다음은 기본적인 킥오프 예제입니다 (명백한 예외 처리는 제쳐두고) :
// Prepare source somehow.
String source = "package test; public class Test { static { System.out.println(\"hello\"); } public Test() { System.out.println(\"world\"); } }";
// Save source in .java file.
File root = new File("/java"); // On Windows running on C:\, this is C:\java.
File sourceFile = new File(root, "test/Test.java");
sourceFile.getParentFile().mkdirs();
Files.write(sourceFile.toPath(), source.getBytes(StandardCharsets.UTF_8));
// Compile source file.
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null, null, null, sourceFile.getPath());
// Load and instantiate compiled class.
URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { root.toURI().toURL() });
Class<?> cls = Class.forName("test.Test", true, classLoader); // Should print "hello".
Object instance = cls.newInstance(); // Should print "world".
System.out.println(instance); // Should print "test.Test@hashcode".
다음과 같은 수익률
hello
world
test.Test@ab853b
해당 클래스 implements가 이미 클래스 경로에있는 특정 인터페이스 인 경우 추가 사용이 더 쉽습니다 .
SomeInterface instance = (SomeInterface) cls.newInstance();
그렇지 않으면 (알 수없는) 메서드 / 필드에 액세스하고 호출하기 위해 Reflection API 를 포함해야 합니다.
즉, 실제 문제와 관련이 없습니다.
properties.load(new FileInputStream(new File("ClassName.properties")));
분들께 java.io.File현재 작업 디렉토리에 의존하는 것은 이동성 문제에 대한 조리법입니다. 그러지 마. 해당 파일을 클래스 경로에 넣고 ClassLoader#getResourceAsStream()클래스 경로 상대 경로와 함께 사용하십시오 .
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("ClassName.properties"));
BalusC의 답변과 같은 맥락이지만, kilim 배포판의이 코드에는 조금 더 자동 래퍼가 있습니다. https://github.com/kilim/kilim/blob/master/src/kilim/tools/Javac.java
Java 소스가 포함 된 문자열 목록을 가져 와서 패키지 및 공용 클래스 / 인터페이스 이름을 추출하고 tmp 디렉터리에 해당 디렉터리 / 파일 계층을 만듭니다. 그런 다음 Java 컴파일러를 실행하고 이름, 클래스 파일 쌍 (ClassInfo 구조) 목록을 반환합니다.
코드에 자신을 도와주세요. MIT 라이센스입니다.
클래스에 인수가없는 공용 생성자가 있다는 것을 알고 있으면 주석 처리 된 코드가 정확합니다. 컴파일러는 클래스가 실제로 .NET을 구현한다는 것을 알 수 없으므로 결과를 캐스팅하면됩니다 IDynamicLoad. 그래서:
IDynamicLoad newClass = (IDynamicLoad) Class.forName(class_name).newInstance();
물론 클래스가 작동하려면 클래스가 컴파일되고 클래스 경로에 있어야합니다.
소스 코드에서 클래스를 동적으로 컴파일하려는 경우 그것은 완전히 다른 물고기입니다.
'program story' 카테고리의 다른 글
| Rails에서 require, require_dependency 및 상수를 다시로드하는 방법은 무엇입니까? (0) | 2020.11.20 |
|---|---|
| PHP에서 간단한 크롤러를 어떻게 만듭니 까? (0) | 2020.11.20 |
| 튜플이 Python의 목록보다 빠른 이유는 무엇입니까? (0) | 2020.11.20 |
| 가능한 인터뷰 질문 : 모든 겹치는 간격을 찾는 방법 (0) | 2020.11.20 |
| manage.py runserver (0) | 2020.11.20 |