Pergunta

Se eu tiver nomes de funções armazenados como strings em uma hashtable.
Existe uma maneira de acessar as funções através das cordas armazenadas?

Editar, receio que a plataforma em que estou trabalhando no cldc1.1/midp2.0 não suporta a reflexão.
Alguma solução alternativa possível?

Foi útil?

Solução

Basta usar uma grande lista longa de else-ifs:

[...]
} else if ("foo".equals(function)) {
    target. foo();
} else if ("bar".equals(function)) {
    target. bar();
[...]

(Embora eu geralmente não goste de tentar alinhamentos verticais na fonte, acho que em casos como esse vale a pena.)

Armazenando um functor no mapa é uma alternativa, a BU pode aumentar demais o tamanho do objeto para muitas aplicações MIDP.

Outras dicas

Class.ForName () e NewInstance () devem estar lá no MIDP 1.1 e podem ser úteis. Como você não tem reflexão total, você pode criar uma classe que envolve todas as chamadas de função e as invoca. Isso pressupõe que você conhece todas as chamadas de função com antecedência.

Você precisará de referências a todos os objetos, a menos que esteja fazendo chamadas estáticas. Meio bagunçado, mas faria o trabalho.

public Object invoke(String name, Object[] args) {
   Object f = functionMap.get(name);
   if("f1".equals(name)) {
       return ((SomeInterface1)f).someFunction1((SomeArg0) args[0]), ...);
   } else if ("f2".equals(name)) {
       return ((SomeInterface2)f).someFunction2((SomeArg0) args[0]), ...);
   }...{
   } else if ("fN".equals(name)) {
       return ((SomeInterfaceN)f).someFunctionN((SomeArg0) args[0]), ...);
   }
}

Dado um nome de função, você pode usar a reflexão para acessar o método. Além do nome da função, você precisa conhecer sua classe e ter (ou criar via reflexão se ele tiver um construtor Noarg ou você sabe quais parâmetros passarem para o construtor) uma instância (se o método não for estático) e você tem que conhecer os parâmetros necessários para passar para ele.

Outra opção é usar a classe de método como um ponteiro para a função. Tem a vantagem de conhecer sua classe e conhecer seus requisitos de parâmetros. Tem a desvantagem de não ser serializável.

EDIT: Não há como acessar um método em Java sem reflexão, apenas tendo esse nome como uma string. Se você deseja um ponteiro alternativo para um método, pode usar uma classe interna anônima que invoca o método que deseja que implemente uma interface conhecida e passasse isso para o seu mapa. Isso não seria apropriado como a chave do mapa, mas funcionaria como um valor no mapa.

Não tentei refletir sobre o Javame, mas no Javase você pode usar a reflexão para chamar dinamicamente um método.

O snippet seguinte é retirado de:http://java.sun.com/developer/technicalarticles/alt/reflection/

import java.lang.reflect.*;

public class Method2 {public int add (int a, int b) {return a + b; }

  public static void main(String args[])
  {
     try {
       Class cls = Class.forName("method2");
       Class partypes[] = new Class[2];
        partypes[0] = Integer.TYPE;
        partypes[1] = Integer.TYPE;
        Method meth = cls.getMethod(
          "add", partypes);
        method2 methobj = new method2();
        Object arglist[] = new Object[2];
        arglist[0] = new Integer(37);
        arglist[1] = new Integer(47);
        Object retobj 
          = meth.invoke(methobj, arglist);
        Integer retval = (Integer)retobj;
        System.out.println(retval.intValue());
     }
     catch (Throwable e) {
        System.err.println(e);
     }
  }

}

EDIT: Em vez de usar o IF..hen..Else, você pode realmente passar de volta um número e usar um switch, pois será mais fácil de ler, IMO.

Mas, independentemente, essa é provavelmente sua única opção, dadas as limitações do Javame.

Eu lido com questões semelhantes em Hecl, um intérprete que é executado no J2ME. Depende de quantas seqüências você deseja lidar, mas um método que funciona é usar o hash para procurar um número inteiro e depois usá -lo em uma instrução SWITCH, em vez da grande lista de instruções IF/Then Then. A propósito, você pode usar o código -fonte HECL; Está disponível sob a licença liberal do Apache.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top