2012-05-26 4 views
1

런타임에 클래스 파일을 편집하여 JVM에서 사용할 수있게하려고합니다. 그럴 수 있습니까? 어떻게해야합니까? 예를 들어변경 클래스 동작을 변경하려면 어떻게해야합니까?

는 :

main() { 
    for (int i=0;i<10;i++) { 
     NewClass.method(); 
     //ask user if to continue.. 
    } 
} 

public class NewClass() { 
    static void method() { 
     sysout("hi"); 
    } 
} 

이 루프가 실행되어, I는 "안녕"인쇄되도록합니다 NewClass 파일()을 변경하고 JVM으로로드 할. 여기

는 전체 코드입니다 : 나는 하나 개의 클래스의 주요 메소드를 실행하려면

try { 
    for (int iCount = 0; iCount < 10; iCount++) { 
     BufferedReader br = new BufferedReader(new InputStreamReader(
       System.in)); 
     System.out.print("Enter which method:"); 
     int i = Integer.parseInt(br.readLine()); 
     System.out.println(i); 
     if (i == 1) { 
      Called.calledMethod1(); 
     } else { 
      Called.calledMethod2(); 
     } 
    } 
} catch (NumberFormatException nfe) { 
    System.err.println("Invalid Format!"); 
} 

, 그리고 내가 다른 클래스를 참조 편집하고, 2 급의 동일한 참조 할 실행되는 동안 메소드를 실행하고 다른 출력을 얻습니다.

  • 다시 코드를 실행
    1. 는 JVM
    2. 편집 코드를 중지 : 내가 할

      은하고 싶지.

    나는

    1. 편집 런타임에 코드를 원하고, 변경 사항이 즉시 반영 얻을.
    +0

    그냥 쉽게 여기 UR 작품을 만들 수는 전체 코드입니다 (체계.에서)); \t \t System.out.print ("어떤 방법 입력 :"); \t int i = Integer.parseInt (br.readLine()); \t System.out.println (i); \t if (i == 1) { \t \t Called.calledMethod1(); \t} \t else { \t \t Called.calledMethod2(); \t} \t} \t \t} 캐치 (NumberFormatException이의 NFE) { System.err.println을 ("잘못된 형식!"); } ** –

    +2

    질문에 코드를 넣어야합니다. –

    +0

    더 나은 설명 : 런타임에 클래스를 동적으로로드하여 해당 메소드 중 하나를 실행하려고 할 수 있습니까? –

    답변

    2

    자바 리플렉션을 사용해야합니다. 반사를 사용하여,

    1. 당신은 ClassforName method를 사용하여 런타임에 동적으로 클래스를로드합니다.
    2. 클래스의 인스턴스에 invoke 메서드를 사용하면 원하는 정적 메서드를 호출 할 수 있습니다.

    클래스가 디자인 타임에 고정되면 첫 번째 지점을 스킵하십시오. 일부 코드 :

    ... 
    
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
    System.out.print("Enter which class:"); 
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 
    className=br.readLine() 
    int results = compiler.run(null, null, null, className+".java"); 
    if(results == 0){ 
    
        Class clazz = Class.forName(className+".class"); 
        System.out.print("Compiled successfully.Enter which method:"); 
        Object returnValue=clazz.getMethod(br.readLine()).invoke(null); 
    } 
    ... 
    

    그러나 보안 문제에주의 : 위의 코드를 누군가가 런타임에 각 클래스의 각 정적 메서드에 액세스 실행 할 수 있습니다. 보안이 걱정된다면 먼저 콘솔에서받은 입력의 유효성을 검사하고 콘솔을 통해 사용할 수있게하려는 클래스 메서드 중 하나와 일치하는지 테스트하는 것이 좋습니다.

    편집 : 나는 당신의 코멘트를 읽은 후

    더 나은 질문을 이해합니다. Java 6를 대상으로하는 경우 런타임에 클래스를 컴파일하려면 Java Compiler object을 사용할 수 있습니다. JavaCompiler 사용법을 포함하도록 코드를 편집했습니다. { \t \t \t의 BufferedReader BR = 새의 BufferedReader (새로운 InputStreamReader (; iCount <10 iCount ++ INT iCount = 0)에 대한 ** 시도 { \t \t :

    +0

    하는 클래스를 입력 : Oldsysoutmethod1 어떤 클래스를 입력 calledMethod1 : 호출 어떤 방법 successfully.Enter를 컴파일 다시하지 않고 내가 Newsysoutmethod1을 같은 방법으로 편집 얻고 싶었다 calledMethod1 Oldsysoutmethod1 : 이 방법 successfully.Enter를 컴파일 호출 메인 자바 프로그램을 실행합니다. 또한 호출 된 Java 파일에 새 메서드를 추가하고 해당 메서드 이름을 입력으로 넣으려고 시도했지만 NoSuchMethodException이 발생했습니다. –

    +0

    동일한 클래스 파일을 다시 class.forname 할 수 있습니까? 이전 클래스 파일을 언로드하고로드하는 중입니다. 편집 된 콘텐츠가있는 동일한 파일 이름. –

    +0

    Pawan : 클래스를 언로드하고 변경된 버전을 다시로드하는 쉬운 해결책은 없습니다. 어쩌면 당신 만의 클래스 로더를 개발할 수도 있지만 쉬운 일은 아닙니다. 아주 쉬운 해결책은 (만약 당신에게 맞는 것이면) 각 편집에서 당신의 클래스 이름을 바꾸거나 패키지 이름을 바꾸는 것입니다. –