2013-07-07 7 views
0

Я составил класс во время выполнения, который я хотел бы использовать на лету, при условии, что его конструктор принимает один параметрОтражение типа несоответствие

package com.notmycompany; 

import com.mycompany.Manager; 
import com.mycompany.Processor; 

import com.mycompany.Event; 

public class CustomProcessor extends Processor { 


    public CustomProcessor(Manager m) { 
     super(m); 
    } 

    @Override 
    public void process(Event evt) { 
     // Do you own stuff 
     System.out.println("My Own Stuff"); 
    } 
} 

Компиляция идет хорошо, и я могу загрузить класс сразу. Но конструктор мне тяжело.

Class<?> clazz = urlClassLoader.loadClass("com.notmycompany.CustomProcessor"); 
Constructor<?> constructor = clazz.getConstructor(com.mycompany.Manager.class); 
this.customProcessor = (Processor) constructor.newInstance(this.manager); 

В этом случае getConstructor бросает NoSuchMethodException

Я попытался с помощью getConstructors вместо этого, который только получает меня один шаг вперед с IllegalArgumentException во время newInstance вызова (конечно this.manager является com.mycompany.Manager)

Constructor<?> list[] = clazz.getConstructors(); 
Constructor<?> constructor = list[0]; 
this.customProcessor = (Processor) constructor.newInstance(this.manager); 

Watever я, существует несоответствие между объектом диспетчера во время выполнения и компиляции
Как я могу исправить эту подпись конструктора?

Edit 1: getParameterTypes выход

 for(Class<?> c : constructor.getParameterTypes()) { 
      System.out.println(c); 
     } 

выходы

class com.mycompany.Manager 


Редактировать 2: Я удалил параметр конструктора в качестве временного решения

Теперь код бросает ClassCastException арбитру, что com.notmycompany.CustomProcessor cannot be cast to com.mycompany.Processor, когда конструктор вызывается:

Constructor<?> constructor = clazz.getConstructor(); 
this.customProcessor = (Processor) constructor.newInstance(); 

Это все кажется, чтобы быть частью одной и той же задачи, в которой классы во время выполнения, кажется несовместимым с компиляцией, хотя имена совпадают.

+1

Что делает 'clazz.getConstructors() [0] .getParameterTypes()' return? – Jeffrey

+0

Добавлено в редактировании, хорошо выглядит. – MonoThreaded

ответ

1

Я был в состоянии заставить его работать в конце концов, после того, как с помощью URL-адреса, который использует currentThread в качестве родителя (в отличие от URLClassLoader, созданного с нуля URL-адресов)

URLClassLoader ucl = (URLClassLoader)Thread.currentThread().getContextClassLoader(); 
URLClassLoader ucl2 = new URLClassLoader(new URL[] { new URL("file://d:/temp/")},ucl); 
Class<?> clazz = ucl2.loadClass("com.notmycompany.CustomProcessor"); 

Я надеюсь, что это может спасти вас 2 дней!

1

Ваш класс CustomProcessor не имеет конструктора, потому что имя метода, который вы считаете своим конструктором, отличается.

public CustomLatencyProcessor(Manager m) { 
    super(m); 
} 

Должен быть изменен на

public CustomProcessor(Manager m) { 
    super(m); 
} 

Поскольку имя вашего класса CustomProcessor. Имена конструктора должны точно соответствовать имени их содержащего класса.

+0

Typo fixed, имя конструктора было правильным в моем коде и теперь корректно в вопросе. И снова этот код компилируется. – MonoThreaded

Смежные вопросы