Pergunta para Mister M

21 respostas
fabioebner

Pessoal e possivel eu passar um METODO da classeA para a classeB e nessa classeB eu executar esse medoto da classeA??

se tiver como… alguem tem uma luz?? um metodo simples mesmo… sem passar parametro e sendo void…

valeus

21 Respostas

thiagocg

Voce pode fazer um metodo (publico ou private pra não ferir o encapsulamento e usar os get’s e set’s) e passar a classeA como parametro para a classeB, instanciando um objeto da classeA vc acessa os metodos dela na classeB

jmag

fabioebner:
Pessoal e possivel eu passar um METODO da classeA para a classeB e nessa classeB eu executar esse medoto da classeA??

se tiver como… alguem tem uma luz?? um metodo simples mesmo… sem passar parametro e sendo void…

valeus

Cara desculpe se eu nao entendi a sua pergunta, Se sua intencao for manter o baixo acoplamento entre varias objetos do sistema,
eu acho que seu problema porde ser resolvido utilizando Injeção de dependência!
Se for isso , acho q essa seria a solucao mais adequada!
Se nao for isso de uma olhadinha no Spring pois ele tem muita coisa a oferecer, simplesmente fantastico!
abracos!

Bani

Não precisa nem passar como parâmetro, pode simplesmente instanciar um objeto da classe A dentro da classe B.
Ou então fazer um método static e chamar diretamente pela classe.

fabioebner

Entao Bani… o problema e q eu nao sei qual Classe eh, o metodo sim, sera sempre o mesmo nome, porem a classe nao… como eu faco isso???

tu tem algum exemplo??

valeu

thiagocg

O fato de passar como parametro seria se voce precisasse, por exemplo, atualizar uma outra tela de onde voce estava!
Quanto a pegar a classe sem saber qual é, e acessar um metodo de nome conhecido, da uma olhadinha nos metodos da classe Class e vc pode usar Reflection tb, tem um ótimo tutorial aqui no guj!

http://www.guj.com.br/java.tutorial.artigo.10.1.guj

Abraço

fabioebner

cara eu fiz o seguinte:

um projeto so com isso:
public class ExecutaMetodo {
   private Method metodo;
   private Class<? extends Container> classe;
    public void guargarMetodo(Class<? extends Container> classe, Method metodo){
        this.metodo = metodo;
        this.classe = classe;
    }
    
    public void executarMetodo() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
        this.metodo.invoke(classe, null);
    }

}

e no meu projeto principal etou chamando assim:

try {
            Class objCls = Class.forName("br.com.dnasolution.gui.GerenciarNaturezaJDL");

            executa.guargarMetodo(objCls, this.getClass().getMethod("metodoX", new Class[]{}));
        } catch (NoSuchMethodException ex) {
            Logger.getLogger(GerenciarNaturezaJDL.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(GerenciarNaturezaJDL.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(GerenciarNaturezaJDL.class.getName()).log(Level.SEVERE, null, ex);
        }


...............

executa.executarMetodo();
sendo que nesse projeto principal nessa classe eu tenho o seguinte metodo
public void metodoX() {
        System.out.println("binhocao");
    }

porem eu recebo o seguinte erro:

java.lang.IllegalArgumentException: object is not an instance of declaring class
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at testeexecutarmetodo.ExecutaMetodo.executarMetodo(ExecutaMetodo.java:25)
        at br.com.dnasolution.gui.GerenciarNaturezaJDL.jbtEditar(GerenciarNaturezaJDL.java:332)
        at br.com.dnasolution.gui.GerenciarNaturezaJDL.access$100(GerenciarNaturezaJDL.java:26)
        at br.com.dnasolution.gui.GerenciarNaturezaJDL$2.actionPerformed(GerenciarNaturezaJDL.java:142)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
        at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
        at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:272)
        at java.awt.Component.processMouseEvent(Component.java:6038)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
        at java.awt.Component.processEvent(Component.java:5803)
        at java.awt.Container.processEvent(Container.java:2058)
        at java.awt.Component.dispatchEventImpl(Component.java:4410)
        at java.awt.Container.dispatchEventImpl(Container.java:2116)
        at java.awt.Component.dispatchEvent(Component.java:4240)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
        at java.awt.Container.dispatchEventImpl(Container.java:2102)
        at java.awt.Window.dispatchEventImpl(Window.java:2429)
        at java.awt.Component.dispatchEvent(Component.java:4240)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:177)
        at java.awt.Dialog$1.run(Dialog.java:1039)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2
JDWP exit error AGENT_ERROR_NO_JNI_ENV(183):  [../../../src/share/back/util.c:820]

ajudae please P

sergiotaborda
fabioebner:
cara eu fiz o seguinte: um projeto so com isso:
public class ExecutaMetodo {
   private Method metodo;
   private Class<? extends Container> classe;
    public void guargarMetodo(Class<? extends Container> classe, Method metodo){
        this.metodo = metodo;
        this.classe = classe;
    }
    
    public void executarMetodo() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
        this.metodo.invoke(classe, null);
    }

}

No invoque vc tem que passar um Objeto da classe certa e não a classe em si. Ou seja, o método tem que ser invocado em cima de algum objeto real.

vc precisa alterar para

public class ExecutaMetodo<T extends Container {
   private Method metodo;
   private Class<T> classe;

    public void guardarMetodo(Class<T> classe, Method metodo){
        this.metodo = metodo;
        this.classe = classe;
    }
    
    public void executarMetodo(T container) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
        this.metodo.invoke(container, null);
    }

}

e

try {  
             Class<T> objCls = Class.forName("br.com.dnasolution.gui.GerenciarNaturezaJDL");  
   
             ExecutaMetodo executa = new ExecutaMetodo()
             
             executa.guargarMetodo(objCls, this.getClass().getMethod("metodoX", new Class[]{}));  

             T instance = objCls.newInstance();

             executa.executaMetodo(instance);

Tem que colocar cast corretos no Class forname. mas o ponto é que vc tem que criar um objeto e invocar o método sobre ele.

fabioebner

Cara eu nao manjo de reflection.. logo ele esta dando uns erros: tipo

Class<T> objCls = Class.forName("br.com.dnasolution.gui.GerenciarNaturezaJDL");
fala q nao acha a classe T
T instance = objCls.newInstance();

mesma coisa. vale lembrar q a classe q executa o metodo nao e do mesmo projeto e apenar um jar q eu vou chamar no meu projeto principal..

na classe ExecutaMetodo do projeto A
public class ExecutaMetodo<T extends Container> {
   private Method metodo;
   private Class<T> classe;
    public void guargarMetodo(Class<T> classe, Method metodo){
        this.metodo = metodo;
        this.classe = classe;
    }
    
    public void executarMetodo(T container) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException{
        this.metodo.invoke(container, null);
    }

}
nao eu erro e o codigo
Class<T> objCls = Class.forName("br.com.dnasolution.gui.GerenciarNaturezaJDL");     
     
            ExecutaMetodo executa = new ExecutaMetodo();   
               
            executa.guargarMetodo(objCls, this.getClass().getMethod("metodoX", new Class[]{}));     
  

                T instance = objCls.newInstance();
                
                executa.executarMetodo(instance);

da classe GerenciarFuncionarioJDL do projeto B e q da os erros.

valeu

g4j

Isso não se resolve com o uso de interfaces?

public interface Comum {
        public void metodoX();
}


public class A implements Comum {
        public void metodoX() {
        }

}

public class Whatever implements Comum {
        public void metodoX() {
        }

}


public class Test {
         public void exec(Comum comum) {
                comum.metodoX();
         }
}
paulofafism

Interface e uma otima solução, essa forma que o g4j abordou vc estará usando padrão de projeto Strategy, tornando sua aplicação muito mais flexivel

sergiotaborda

fabioebner:
Cara eu nao manjo de reflection… logo ele esta dando uns erros: tipo

Class<T> objCls = Class.forName("br.com.dnasolution.gui.GerenciarNaturezaJDL");

fala q nao acha a classe T

T instance = objCls.newInstance();

T não é uma classe é um tipo generico.
Se não funciona retire os T. Use Class em vez de Class e Object em vez de T.

fabioebner

E mlkao nada feito.. agora eu recebo o seguinte erro:

03/10/2008 09:08:57 br.com.dnasolution.gui.GerenciarFuncionarioJDL SEVERE: null java.lang.InstantiationException: br.com.dnasolution.gui.GerenciarNaturezaJDL at java.lang.Class.newInstance0(Class.java:340) at java.lang.Class.newInstance(Class.java:308) at br.com.dnasolution.gui.GerenciarFuncionarioJDL.(GerenciarFuncionarioJDL.java:46) at notas.Main.main(Main.java:31)
o meu codigo esta asim:
Class objCls;     
     
            ExecutaMetodo executa = new ExecutaMetodo();   
        try {
            objCls = Class.forName("br.com.dnasolution.gui.GerenciarFuncionarioJDL");
          executa.guargarMetodo(objCls, this.getClass().getMethod("metodoX", new Class[]{}));     
  

                Object instance = objCls.newInstance();
                
                executa.executarMetodo(instance);             
        } catch (Exception ex) {
            Logger.getLogger(GerenciarFuncionarioJDL.class.getName()).log(Level.SEVERE, null, ex);
        }
e a classe q vai executar o metodo esta assim:
private Method metodo;
   private Class classe;
    public void guargarMetodo(Class classe, Method metodo){
        this.metodo = metodo;
        this.classe = classe;
    }
    
    public void executarMetodo(Object obj) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException{
        this.metodo.invoke(obj, null);
    }
obs a classe q estou tentando instanciar e essa
public class GerenciarFuncionarioJDL extends javax.swing.JDialog {

abracos

g4j

Cara, precisa mesmo fazer com reflection? Não pensou na possibilidade de usar interface?

fabioebner

g4j entao cara nao da para fazer com interface nao… pq o nome do metodo vai ser sempre o mesmo porem o conteudo muda de classe para classe, e a classe q vai executar esse metodo sabe qual classe eu esou recebendo ou o conteudo do metodo… apenas executar. entendeu

g4j

Mas é isso mesmo que o modelo com interfaces se propõe. Vc não precisa saber que classe concreta vai executar, mas vc sabe que é uma classe que implementa a interface Comum, que tem o tal metodoX. Aí em todas as classes que vc quer passar para a execução vc implementa a interface Comum, que força vc a implementar o metodoX.

interface Comum {
	public void metodoX();
}

class GerenciarFuncionarioJDL implements Comum {
	public void metodoX() {
		System.out.println("Execução métodoX de GerenciarFuncionarioJDL");
	}
}

class QualquerClasseQueTenhaMetodoX implements Comum {
	public void metodoX() {
		System.out.println("Execução métodoX de QualquerClasseQueTenhaMetodoX");
	}
}

class MaisUmaQueTenhaMetodoX implements Comum {
	public void metodoX() {
		System.out.println("Execução métodoX de MaisUmaQueTenhaMetodoX");
	}
}


class ExecutaMetodo {
	public void executar(Comum comum) {
		comum.metodoX();
	}
}


public class ExecutaMetodoTest {
	public static void main(String[] args) {
		ExecutaMetodo executaMetodo = new ExecutaMetodo();
	
		executaMetodo.executar(new GerenciarFuncionarioJDL());
		executaMetodo.executar(new QualquerClasseQueTenhaMetodoX());
		executaMetodo.executar(new MaisUmaQueTenhaMetodoX());
	}
}
J2Alex

Seu problema é facilmente resolvido com a utilização de interface sim… você está confundindo as coisas.

fabioebner

pessoal vcs q nao entenderam… eu tenho q passar esse metodo para OUTRA classe executar ele… eu tenho a CLASSEA que tem o metodoX, a CLASSEB tbm tem o metodoX(porem com outra funcionalidade) a CLASSEC tem o metodoX (com outra funciondalidade)

agora eu tenho uma CLASSEEXECUTAMETODOX q recebe o metodo X e dependendo de alguma verificacao executa ou nao o metodoX entendeu???

o meu problema q e eu tenho q criar uma classe q executa o metodo de outra classe sem conhecer a mesma… por isso do reflection…

eu recebo uma classe QUALQUER e executo o metodoX daquela classe. sem precisar saber o q ele faz ou nao

g4j

Vamos por partes:

Não precisa passar o método, passa uma classe que implementa a interface que provê garantia de implentação do metodoX

Exatamente!!! Vc não sabe qual é!

a tal classe que executa o metodoX é essa aqui! só que vc passa a classe que implementa a interface Comum pro método “executar” ao invés de passar um método.

class ExecutaMetodo {  

     public void executar(Comum comum) {  
         //executa o metodoX de QUALQUER classe que implementa a interface Comum.

         //VERIFICA O QUE QUER QUE SEJA:
         if(.........) {
                comum.metodoX();  
         }
     }  
 }

fabioebner:
“…” eu tenho a CLASSEA que tem o metodoX, a CLASSEB tbm tem o metodoX(porem com outra funcionalidade) a CLASSEC tem o metodoX (com outra funciondalidade) “…”

São essas: Note que todas elas implementam a interface Comum, portanto, garante que ela tenha o metodoX implementado.

class ClasseA implements Comum {  //CLASSEA !
     public void metodoX() {  
         System.out.println("Execução métodoX de GerenciarFuncionarioJDL");  
     }  
 }  
   
 class ClasseB implements Comum {  //CLASSEB !
     public void metodoX() {  
         System.out.println("Execução métodoX de QualquerClasseQueTenhaMetodoX");  
     }  
 }  
   
 class ClasseXYZ implements Comum {  //CLASSE XYZ!
     public void metodoX() {  
         System.out.println("Execução métodoX de MaisUmaQueTenhaMetodoX");  
     }  
 }

Sacou?

fabioebner

boa mlkao… acho q funcionou sim. .pelo menos o teste q eu fiz aqui deu certo… deixa eu fazer o punk agora… so uma coisa… como a classe q tem o metodoX e a classe q vai executar estao em PROJETOS diferentes eu tenho q ter a mesma interface no mesmo pacote em ambos os projetos neh??

pq a classe q executa o metodo nao e a principal… e um componente da principal entendeu

g4j

Tem que ser a mesma interface cara. Vc vai ter que empacotar tuas classe em um arquivo .jar. Aí vc pode executar em qualquer projeto.

M

cara, muda pra um metodo de classe e esta pronto.

Criado 1 de outubro de 2008
Ultima resposta 6 de out. de 2008
Respostas 21
Participantes 9