InvokeExact для объекта, тип которого динамически загружается загрузчиком классов

Я потратил целый день на эту проблему. Моя проблема заключается в том, как сделать метод MethodHandle.invokeExact для экземпляра, тип класса которого динамически загружается во время выполнения программы. Чтобы сделать проблему более ясной, я показываю мой пример кода ниже:

Class<?> expClass = new MyClassLoader().load(....)

//expClass is AddSample.class which is subclass of BaseTemplate         
 BaseTemplate obj = expClass.getConstructor(...)
                .newInstance(...);
MethodHandle myMH = MethodHandles.lookup().findVirtual(expClass, methodName,..);
System.out.println("Object type "+obj.getClass()); //Print AddSample

// If obj is declared as "AddSample obj", the runtime would be OK.
assertEquals((int)myMH.invokeExact(obj,"addintaasdsa" , 10 , 20.0f), 12);

В этом примере expClass загружается динамически, и его тип классаAddSample, Экземпляр obj в следующей строке объявляется как BaseTemplate, а его реальный типAddSample, Класс AddSample является подклассом BaseTemplate. Затем MethodHandle myMh создается для функции добавленияAddSample но вызов myMH терпит неудачу, потому что receiveType не совпадает.

myMH.invokeExact вызывает ошибку во время выполнения

java.lang.invoke.WrongMethodTypeException: expected (AddSample,String,int,float)int but found (Object,String,int,float)int

потому что получатель этогоmyMH объявляется как expClass (AddSample), но получательobj текущий предоставленный объявлен BaseTemaplte, хотя класс объекта является AddSample. InvokeExact требует точного соответствия параметров.

Моя проблема может быть упрощена как: как привести экземпляр из его базового типа к дочернему типу, который динамически загружается?

BaseTemplate obj = ...
Class<?> newType = Class('AddSample') //dynamic loaded...
изменить объявленный тип obj на AddSample, который динамически загружается ..?

UPDATE:

Class<T> expClass = (Class<T>) new MyClassLoader().run(className, methodName, b);
BaseTemplate obj = ..
Class<T> newType = (Class<T>) obj.getClass().getClassLoader().loadClass("AddSample");
T tObj = newType.cast(obj);
assertEquals((int)myMH.invokeExact(tObj,"addintaasdsa" , 10 , 20.0f), 12);

Использование броска не помогает решить проблему, которая является тем же самым предыдущим результатом. Причина по-прежнему заключается в том, что данный параметр не точно соответствует объявлению myMH. Было бы более понятно, когда я проверяю сгенерированные байт-коды:

L23  # For cast 
    LINENUMBER 126 L23
    ALOAD 10: newType
    ALOAD 8: obj
    INVOKEVIRTUAL Class.cast (Object) : Object  #tObj is Object and its real type is AddSample here
    ASTORE 11
   L24
    LINENUMBER 128 L24
    ALOAD 9: myMH           # Push myMH to stack
    ALOAD 11: tObj          # Push tObj to Stack. tObj is declared Object type and its real type is AddSample. 
    LDC "addintaasdsa"      #Push String to Stack
    BIPUSH 10               #Push int to Stacl
    LDC 20.0                #Push float to Stack 
    INVOKEVIRTUAL MethodHandle.invokeExact (Object, String, int, float) : int

myMH указывает на(AddSample,String,int,float)int, но с учетом параметров:(Object, String, int, float), и это приводит к ошибке во время выполнения, которая мне была показана ранее.

Спасибо

Ответы на вопрос(2)

Ваш ответ на вопрос