2017-02-17 4 views
2

У меня есть суперкласс OpCode и подклассы Добавить/And..etcрефлекторно экземпляр класса с конструктором, который принимает Enum

Я пытаюсь построить рефлекторно подклассы на основе их имя класса строки. Конструктор принимает перечисление, определенное в суперклассе.

Я пытаюсь:

OpCode theOpCode = (OpCode) Class.forName("com.sstangle.opCodes." + opCodeName).getConstructor(OpCode.OpEn.class).newInstance(opEn); 

что приводит к

java.lang.NoSuchMethodException: com.sstangle.opCodes.Add.<init>(com.sstangle.opCodes.OpCode$OpEn) 
    at java.lang.Class.getConstructor0(Unknown Source) 
    at java.lang.Class.getConstructor(Unknown Source) 

Надстройка Класс

public class Add extends OpCode { 
    Add(final OpEn opEn) { 
     super(opEn); 
     this.assemblyCommand = "ADD"; 
    } 
} 

Класс OpCode является

public abstract class OpCode { 
    OpCode(final OpEn opEn) { 
     this.opEn = opEn; 
    } 
    public static enum OpEn { 
     I, MI, MR, RM, ZO 
    } 
} 

Как правильно получить доступ к конструктору с перечислением?

Благодаря

+0

Этот конкретный класс не имеет такого конструктора, который использует 'com.sstangle.opCodes.OpCode $ OpEn'. Можете ли вы показать конструкторы класса «Добавить»? –

+0

@ ЭндиТурнер обновлен. –

+3

Проблема в том, что ctor не является общедоступным. Попробуйте сделать его общедоступным или используя 'getDeclaredConstructor'. –

ответ

3

Посмотрите на source code of Class.getConstructor:

public Constructor<T> getConstructor(Class<?>... parameterTypes) 
    throws NoSuchMethodException, SecurityException { 
    checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true); 
    return getConstructor0(parameterTypes, Member.PUBLIC); 
} 

Это Member.PUBLIC рассказывает метод getConstructor0 только вернуть публичный конструктор.

private Constructor<T> getConstructor0(Class<?>[] parameterTypes, 
            int which) throws NoSuchMethodException 
{ 
    Constructor<T>[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC)); 
    for (Constructor<T> constructor : constructors) { 
     if (arrayContentsEq(parameterTypes, 
          constructor.getParameterTypes())) { 
      return getReflectionFactory().copyConstructor(constructor); 
     } 
    } 
    throw new NoSuchMethodException(getName() + ".<init>" + argumentTypesToString(parameterTypes)); 
} 

где privateGetDeclaredConstructors принимает булево параметр называется publicOnly:

private Constructor<T>[] privateGetDeclaredConstructors(boolean publicOnly) 

Либо сделать конструктор public, или использовать getDeclaredConstructor вместо этого.

+0

Вы имеете в виду конструктор "ctor"? –

+2

@ GrzegorzGórkiewicz yep. –

+1

«ctor» - стандартная сокращенная форма «конструктора». –