Wpis z mikrobloga

#java | #programowanie | #mechanizmrefleksji | #refleksja

Dobra dzisiaj już raz pisałem to napiszę jeszcze raz.
Piszę projekcik na studia i stwierdziłem że jest fajna okazja żeby ogarnąć refleksję. Bo czemu nie.
No i sytuacja przedstawia się następnująco.

Mam taką ścieżkę dziedziczenia po klasach:
Creature -> Animal -> Wolf.

Powiedzmy że gdzieś w jakiejś klasie chcę utworzyć sobie nową instancję tego wilka z tym, że nie wiem o tym że to jest wilk.
Metoda wygląda tak:

public void addCreature(int x, int y, Creature c)
I tutaj trochę przeszukując stack'a wymodziłem coś takiego:

Creature newCreature = (Creature) Class.forName(c.getClass().getName()).getConstructor(c.getClass()).newInstance(x, y, this);
Akurat to ma być wywoływane w klasie World, dlatego jest 'this'.
Konstruktor wilka wygląda następująco (nie ma dodatkowych):

public Wolf(int x, int y, World world)
Wywołując kod który wkleiłem wyżej dostaję wyjątek że nie znalazł takiej metody:

java.lang.NoSuchMethodException: com.m.VirtualWorld.Animals.Player.(com.m.VirtualWorld.Animals.Player)
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getConstructor(Class.java:1825)

I wyrzuca ten wyjątek właśnie przy Creature newCreature = ....;

Wszystko co googluję sprowadza właśnie do takiej postaci tworzenie nowych obiektów, dlatego strzelam że coś pomieszałem w argumentach dla metod .forName() albo .getConstructor();
Ktoś/coś jest w stanie podpowiedzieć?

#java #programowanie #refleksja
  • 22
Nie jestem pewien, ale gdyby to zadziałało tak jak chcę to oszczędziłoby mi odrobiny kodu.


@Wyrewolwerowanyrewolwer: Jeśli refleksja zaoszczędzi Ci kodu, to znaczy, że design masz do dupy.
Wytłumacz dlaczego uważasz, że potrzebujesz refleksji, to coś może coś zaradzimy .:)
W sumie to nie jestem pewien, czy to była przyczyna, więc usunąłem moją diagnozę. Pokaż cały kod to powiem.

Ale używanie refleksji jest z wielu powodów złe - nieczytelny kod, dużo wolniej działa, wprowadza nieoczywiste zależności, uniemożliwia IDE (eclipsowi czy czego tam używasz) poprawne parsowanie kodu (bo nie wiadomo, jaka metoda jest wołana, więc call graph np. nie zadziała).

Ogólnie to refleksje to ostateczność.
@sorhu:
Mam w świecie kontener wszystkich organizmów które są w nim obecne. Organizmy mogą się rozmnażać, ale nie mogę ich tak po prostu dodać do jednej listy bo każdy z nich ma swój priorytet według którego jest przydzielany do odpowiedniej listy.
Do tego organizmy na świecie mogą się rozmnażać, a akcje niektórych są domyślnie takie same dlatego metoda akcji jest przerzucona do klasy nadrzędnej (powiedzmy Animal dla każdego zwierzęcia) i tam
@Wyrewolwerowanyrewolwer: zgodnie z zasadą "tell don't ask" zamiast w kodzie na zewnątrz klasy pytać rodzica o jego klasę i na tej podstawie decydować w ifie co zrobić - dodaj do klasy Animal metodę "reproduce" i przedefiniuj ją w każdej podklasie żeby zrobiła co trzeba i zwróciła nowego Animal (a tak naprawdę nowe zwierze odpowiedniej klasy).

Możliwe nawet, że metoda Object.clone() Ci się przyda, ale to zależy.
@sorhu:
Organizmy mają to do siebie że niektóre są ważniejsze niż reszta i akcje organizmów nie są wywoływane po prostu w kolejności dodania do świata tylko według tego priorytetu. Np. A jest ważniejsze(ma wyższy priorytet) niż B, dlatego wywołanie:
B.akcja();
A.akcja();
Jest błędne, ponieważ poprawną kolejnością jest
A.akcja();
B.akcja();