Jak zaimplementować metodę:
public <T> T get(Class<T> clazz)
która zwraca obiekt zadanej klasy, z tym, że:
- jeśli jest to pierwsze pytanie o obiekt, to go tworzy
- jeśli kolejne, to zwraca wcześniej utworzony
- jeśli klasa posiada pola oznaczone adnotacją Inject, to metoda ustawia te pola wg powyższych zasad
- inaczej, obiekty utworzone dla danej instancji Injector są singletonami
A z którym elementem masz problem?
Z wszystkimi, nie wiem jak sie za to zabrać
No to zalecam jakiś kurs javy bo innej drogi nie ma.
Doczytaj o refleksji.
stwórz sobie mapę gdzie będziesz wkładał typy klas jako klucze i obiekt jako wartość. Jeżeli nie masz w mapie klucza to tworzysz nowy obiekt i wkladasz do mapy z kluczem.
Pytanie tylko jak tworzyc obiekt skoro nie znamy w ogóle jego typu.... przez newInstance pewno można ;) a najlepiej zrób jak radzi Shalom :)
Mamy sobie taki twór jak Class<T>
, czyli klasę reprezentującą klasę T. W metodzie otrzymujemy obiekt klasy reprezentującej klasę i na jej podstawie chcemy utworzyć obiekt klasy. Klasykę mamy za sobą > http://roflcopter.pl/631
Zatem bazując na sygnaturze możemy napisać:
public <t> T get(Class<t> clazz){
return clazz.newInstance()
}
I jest prawie OK (dokumentacja> https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#newInstance--), bo to zadziała tylko dla klas, które mają publiczny konstruktor bezargumentowy. Jeżeli klasa ma jakieś konstruktory to musisz przekazać odpowiednie parametry, ale doczytaj sobie o tym w dokumentacji:
https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html
https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Constructor.html
Jeżeli jako parameter przekażesz klasę, która reprezentuje interfejs, to możesz użyć mechanizmu Proxy
z pustym InvocationHandler
, czyli takim co zawsze zwróci null
, albo rzuci UnsupportedOperationException
. Względnie sprawdzić za pomocą isInterface
i od razu rzucić wyjątek.