2012-06-29 3 views
0

У меня есть перечисление в коде JAVA ERequestTypes мое перечисление содержит более 20 элементов, каждый элемент - это имя функции в моем коде JAVA. Теперь я хочу сделать следующую вещь вместо того, чтобы писать switch(ERequestTypes) case и случаи вызова функции следующим образом:Функция вызова из перечисления

switch(ERequestTypes a) { 
    case ERequestTypes.Initialize: 
     Initialize(); 
    case ERequestTypes.Uninitialize: 
     Uninitialize(); 
} 

Я хочу сделать это с одной линией. Все функции в перечислении имеют одинаковый аргумент и возвращают одинаковое значение int. Как я могу это сделать? могут содержать указатели функций в перечислении, как на C++ или что-то еще. Пожалуйста помоги !

class CRequestValue { 
    /** 
    * Constructor. 
    * 
    * @param aName - Name of the request. 
    * @param aCode - Code of the request. 
    */ 
    public CRequestValue(String aName, int aCode) { 
     this.mName = aName; 
     this.mCode = aCode; 
    } 

    private String mName; 
    private int mCode; 

    public String GetName() { 
     return this.mName; 
    } 

    public int GetCode() { 
     return this.mCode; 
    } 

} /* class CRequestValue **/ 

enum ERequestTypes 
{ 
    Initialize(new CRequestValue("Initialize", 0)), 
    Uninitialize(new CRequestValue("Uninitialize", 1)), 
    GetDeviceInfoList(new CRequestValue("GetDeviceInfoList", 2)), 
    GetDeviceInfo(new CRequestValue("GetDeviceInfo", 3)); 

    private CRequestValue mRequestValue; 

    private ERequestTypes(CRequestValue aRequestValue) { 
     this.mRequestValue = aRequestValue; 
    } 

    public String GetName() { 
     return this.mRequestValue.GetName(); 
    } 

    public int GetCode() { 
     return this.mRequestValue.GetCode(); 
    } 

} /* enum ERequestTypes **/ 
+0

Почему вы хотите упорядочить функции в перечислении? Какова цель вашего шаблона проектирования? –

+0

Java, а не JAVA. – missingfaktor

ответ

2

Вы ищете reflection.

ErequestTypes a = <init>; 
Object o = Class.forName(<your class name>).getMethod(a.getName(), <argtype>.class).invoke(<instance of your class, or null if static method>, <arg>); 

Обратите внимание, что Class.forName не требуется, если вы уже знаете, какой класс метода в.

3

Я не уверен, что ваша цель, но вы можете использовать полиморфизм вместо блока переключателей , например:

interface Invokable { 
    int init(Object arg); 
    int uninit(Object arg); 
} 

enum Request { 
    INIT() { 
     @Override 
     public int invoke(Invokable invokable, Object arg) { 
      return invokable.init(arg); 
     } 
    }, 
    UNINIT() { 
     @Override 
     public int invoke(Invokable invokable, Object arg) { 
      return invokable.uninit(arg); 
     } 
    }, 
    ; 
    public abstract int invoke(Invokable invokable, Object arg); 
} 


Invokable i = ....; 
Object arg = ....; 
Request r = Request.INIT; 
r.invoke(i, arg); // should invoke Invokable.init(arg); 
r = Request.UNINIT; 
r.invoke(i, arg); // should invoke Invokable.uninit(arg); 
0

вы могли бы пойти с полиморфизмом, что упомянутый Павел, но есть другое решение - вы на самом деле не нужно перечисление вообще.

Весьма просто сделать каждую функцию ее собственным объектом и просто обойти/использовать экземпляры этих объектов, как и сами перечисления.

Существует также несколько решений с использованием анонимных внутренних классов (привязка их к объектным экземплярам и передача этих экземпляров), но я не думаю, что это обычно можно использовать повторно как отдельные отдельные объекты.

Вот некоторый поддельный код:

public void MainClass { 
    private final Runnable init=new Runnable { 
     run() { 
      // Initialize the system 
     } 
    } 
    private final Runnable uninit = new Runnable() { 
     run() { 
      // Uninitialize the system 
     } 
    } 

public someMethod() { 

    // At this point you can treat the instances as you would any variable... 
    Runnable nextOperation = init; 

    // and executing whichever one you have is as simple as: 
    nextOperation.run(); 

Если вы хотите, «Тип безопасность» (как с перечислениями) не распространяется Runnable, но создать новый класс, который расширяет работоспособным затем продлить этот класс.

Поскольку это «внутренние классы» (определенные внутри контекста другого класса), они могут получать доступ и изменять все переменные-члены классов, что делает их более похожими на независимые методы, чем автономные классы.

Наконец, обратите внимание на то, что, поскольку каждый класс определен анонимно, он почти так же сложно создать «Дубликаты» как перечисления, поэтому вы можете в целом относиться к ним точно как перечисления (например, вместо «==» вместо. equals().

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