2016-12-03 1 views
2

방금 ​​javassist를 사용하기 시작했고 런타임에 클래스를 인스턴스화하는 방법을 파악할 수 없습니다.javassist를 사용하여 런타임에 생성 된 클래스를 인스턴스화하는 방법은 무엇입니까?

makeNewClass() 방법은 NewClass 클래스처럼 만드는 :

public bin.objects.base.NewClass { 
    public int quantity = 5; 
    private float weight = 30.25f; 

    public float getWeight() { return weight; } 
    public void setWeight(float weight) { this.weight = weight; } 
    public float totalWeight() { return quantity * getWeight(); } 
} 

이 방법은 잘 작동합니다 :

public void makeNewClass() throws NotFoundException, IOException, CannotCompileException { 
     // ClassMaker maker holds the CtClass object and handles all the "making" 
     ClassMaker maker = new ClassMaker("bin.objects.base.NewClass"); 

     maker.addField(CtClass.intType, "quantity", "5", Modifier.PUBLIC); 
     maker.addField(CtClass.floatType, "weight", "30.25f", Modifier.PRIVATE); 

     maker.addMethod(Modifier.PUBLIC, CtClass.floatType, "totalWeight", null, null, 
       "{ return quantity * getWeight(); }", null, MethodType.standard); 
     maker.getCtClass().writeFile(); 
    } 

지금 문제를 시작합니다. 이 메소드는 NewClass을 인스턴스화하고 해당 필드를 액세스하여 메소드라고합니다.

public void testNewClass() 
      throws Throwable { 
     CtClass ctclass = ClassPool.getDefault().get("bin.objects.base.NovaClasse"); 

     Object testClass = ctclass.toClass(new Loader(), null); 

     // Throws NoSuchFieldException 
     Field q = testClass.getClass().getDeclaredField("quantity"); 
     int quantity = (int) q.get(testClass); 

     Class[] cArg = new Class[1]; 
     cArg[0] = Float.class; 

     // Throws NoSuchMethodException 
     Method m = testClass.getClass().getDeclaredMethod("getWeight", cArg); 
     float weight = (float) m.invoke(testClass, null); 

     // Throws NoSuchMethodException 
     m = testClass.getClass().getDeclaredMethod("totalWeight", cArg); 
     float totalWeight = (float) m.invoke(testClass, null); 

     System.out.println("quantity = " + quantity + 
       "weight = " + weight + 
       "totalWeight = " + totalWeight); 
    } 

지금, 나는 이미 TestClass에 실제로 java.lang.Class하지 bin.objects.base.NewClass의 인스턴스로 초기화 있다고 알아 냈어. 따라서 NewClass의 필드와 메서드를 찾을 수 없습니다.

질문은 어떻게 해결합니까? java.lang.Class.cast() 메서드를 사용해 보았지만 성공하지 못했습니다.

+0

코드가 절반의 절반을 번역하거나 변수 이름과 함께 jumbling 수 있습니다 보인다. 제발 그걸 고칠 수 있을까요. – nullpointer

+0

예. 나는 번역에서 약간의 이름을 놓쳤다. 나는 이제 괜찮다고 생각한다. –

답변

1

나는 결국 문제가 무엇인지 알아낼 수있었습니다.

분명히 ClassLoader에 문제가있었습니다. 나는 대답을 발견했다 in this post.

Class newClasse = ctclass.toClass(this.getClass().getClassLoader(), 
    this.getClass().getProtectionDomain()); 

도 도움이 nullpointer의 대답 @ : 그것을 해결하기 위해, 난 그냥이 줄을 포함.

그래서 좀 더 변경 후 testNewClass() 방법은 다음과 같이 결국 :

public void testNewClass() 
      throws Throwable { 
     CtClass ctclass = ClassPool.getDefault().get("bin.objects.base.NewClass"); 
     Class newClass = ctclass.toClass(this.getClass().getClassLoader(), 
      this.getClass().getProtectionDomain()); 
     Object objNewClass = newClass.newInstance(); 

     System.out.println("Accessing the field 'public int quantity'..."); 
     Field q = newClass.getDeclaredField("quantity");   
     int quantity = (int) q.get(objNewClass); 
     System.out.println("quantity = " + quantity); 

     System.out.println("\nAccessing the field 'private float weight' " + 
      "through the method 'public float getWeight()'..."); 
     Method m = newClass.getDeclaredMethod("getWeight", null); 
     float weight = (float) m.invoke(objNewClass, null); 
     System.out.println("weight = " + weight); 

     System.out.println("\nAccessing the method 'public float totalWeight()'..."); 
     m = newClass.getDeclaredMethod("totalWeight", null); 
     float totalWeight = (float) m.invoke(objNewClass, null);   
     System.out.println("totalWeight = " + totalWeight); 
    } 
0

로 클래스 객체 얻기 위해 반사를 사용해보십시오 : 당신은뿐만 아니라 다른 분야에 대해 동일한 작업을 수행 할 수 있습니다

Field q = Class.forName("bin.objetos.base.NovaClasse").getDeclaredField("quantity"); 

합니다.

+0

작동하지 않았습니다. 그것은 ClassNotFoundException을 던집니다. 그러나 어쨌든 고마워. –

+0

@BrunoNascimento 클래스 로더를 통해 클래스를로드 했습니까? –

+0

질문에서 혼란 스러울 때,'Class.forName ("bin.objetos.base.NewClass")'한번 시도해보십시오. – nullpointer

관련 문제