[Java] Dynamiczne uruchamianie metod klas

0

Mam mały problemik - jak uruchomic metodę klasy z poziomu aplikacji - podajac jej nazwe w trakcie dzialania aplikacji... (z początku nie znamy nazwy klasy).

Program tworzę w konsoli i działa na takiej zasadzie :

  • użytkownik wpisuje polecenie
  • system szuka czy istnieje klasa o nazwie takiej samej jak wpisane polecenie
  • jeżeli znajdzie - uruchamia odpowiednią metodę tej klasy

Jeszcze troche zielony jestem w Javie, wiec wszelkie wskazowki mile widziane..

0

import java.lang.reflect.*;
public class test {
public static void main(String[] args)
{
if(args.length == 0)
{
System.out.println("Nie podałeś nazwy klasy");
return;
}

    try
    {
        Object obj = Class.forName(args[0]).newInstance();
        Method m = obj.getClass().getMethod("ruszaj",null);
        m.invoke(obj,null);
    }
    catch(Exception e)
    {
        System.out.println("Nie ma takiej klasy");
    }
    
}

}

class samolot
{
public samolot()
{

}

public void ruszaj()
{
    System.out.println("SAMOLOT: zaczynam leciec");
}

}

class auto
{
public auto()
{

}

public void ruszaj()
{
    System.out.println("AUTO: zaczynam jechac");
}

}

// KONIEC

wpisz w linia poleceń (po skompilowaniu):
java test auto
java test samolot

0

[browar] dzięki mistrzu [browar]

zaraz implementuje... :]

Pozdrawiam.

0

tutaj w tym przykladzie metody nie maja zadnych parametrow , a jak zrobic gdy takowe metody maja jkaies parametry , gdzie sie je umieszcza ??

np gdy metoda clasy samolot ruszaj wyglada nastepujaco
public void ruszaj(String miasto)
{
System.out.println("SAMOLOT: zaczynam leciec do "+miasto);
}

0
public Object Uruchom(String klasa, String metoda, String argument1, Integer argument2)
{

// szukamy podanej klasy
Class Kl = Class.forName(klasa);

// szukamy metody podanej klasy
Method Met = Kl.getMethod(metoda, new Class[] { Class.forName("java.lang.String") } );

// uruchamiamy metodę z podanymi argumentami i zwracamy wynik
return Met.invoke(null, new String[] { new String(argument) }, Integer.TYPE );

}

co do tego integera głowy nie dam, ale powinno być dobrze :-)

Pozdrawiam!

0

import java.lang.reflect.;
public class test2 {
private static final Object []obj2={Boolean.TYPE};
public static void main(String[] args)
{
/
if(args.length == 0)
{
System.out.println("Nie podae nazwy klasy");
return;
}
*/
try
{
String s="samolot";
Object obj = Class.forName(s).newInstance();
Method m = obj.getClass().getMethod("ruszaj",new Class[]{Boolean.TYPE,Integer.TYPE,String.class});

        m.invoke(obj,new Object[]{Boolean.TRUE,new Integer(555555),new String("moj string")});
       
    }
    catch(Exception e)
    {
        System.out.println("Nie ma takiej klasy "+e);
    }
    
}

}

class samolot
{
public samolot()
{

}

public void ruszaj(boolean b,int i2,String s)
{
    System.out.println("SAMOLOT: zaczynam leciec "+b+"  "+i2+"  "+s);
}

}

class auto
{
public auto()
{

}

public void ruszaj(int i)
{
    System.out.println("AUTO: zaczynam jechac "+i);
}

}

0

Wszystko pieknie. Reflection jest rzeczywiście mocnym mechanizmem, ale czy aby przypadkiem nie stosujecie armaty na komara? Przecież do zrobienia takiego czegoś jak chce Eskim wystarczą zwykłe interfejsy Javy, no może poza dynamicznym tworzeniem obiektu na podstawie nazwy klasy wczytanej z klawiatury. Co innego jeśli również nazwa metody miałaby być wczytywana z klawiatury, ale to jest raczej dosyć niebezpieczne, bo wtedy złośliwy użytkownik mógłby powołać do życia obiekt dowolnej klasy i wywołać niemal dowolną metodę. Jakie to może mieć skutki nie trudno sobie wyobrazić.

<java> interface IRuchomy { public void ruszaj(); }

class Samochod: IRuchomy {
public void ruszaj() { ... }
};

class Samolot: IRuchomy {
public void ruszaj() { ... }
};

...

IRuchomy Kl = (IRuchomy)class.forName(klasa).createNewInstance();
Kl.ruszaj();
</java>

To rozwiazanie, zwane wzorcem "command", ogranicza zakres wywolanych metod oraz klas (tylko te implementujace IRuchomy moga byc wywolywane).

0

Królik napisał :

Przecież do zrobienia takiego czegoś jak chce Eskim wystarczą zwykłe interfejsy Javy, no może poza dynamicznym tworzeniem obiektu na podstawie nazwy klasy wczytanej z klawiatury.</quote>

Przecież ja chciałem tylko to... :] + wywołanie metody załadowanej klasy, więc powiedzenie "stosowanie armaty na komara" w tym kontekście jest raczej błędne

Twoje rozwiązanie uruchamiania metod wygląda znacznie ładniej (w moim programie uprościłoby mi znacznie kod i dało większą elastyczność), ale niestety nie działa.. Poprawiłem literówki (klasa Class, a nie class) i :

class Samolot <b>implements</b> IRuchomy 
{
 public void ruszaj() { ... }
}

class Samolot <b>implements</b> IRuchomy 
 public void ruszaj() { ... } 
};

Wyskakuje mi jednak jeden błąd podczas kompilacji :

K1.ruszaj() 
  • wymagany identyfikator

Pozdrawiam!

0

No tak, nawyki z C++ się kłaniają. Dzięki. :)

Ale dlaczego Ci wywala błąd w tej linijce, to nie potrafię powiedzieć. Może literówka?

1 użytkowników online, w tym zalogowanych: 0, gości: 1