Generics - Wydobycie nazwy klasy

0

Hej.

public class Player<T> implements User<T>

Czy dam rady w jakiś sposob w definicji wyłukać nazwe klasy konkretnej T ? np. mam tam metode ktora ma sie zachowac w inny sposob w zaleznosci od typu T.

0

Nie. Java ma type erasure. W trakcie wykonania programu nie ma informacji o typie. Oczywiście jeśli masz gdzieś w Player pole typu T to możesz sobie je wyciągnąć i refleksja odczytać nazwę klasy, ale to zły pomysł. Na oko masz błąd w projekcie. Napisz konkretnie co robisz i co chcesz osiągnąć.

0

Chce w pewnym momencie w klasie Player wykonac np. cos takiego:

entityManager.createQuery("from **T**").getResultList()
Zeby nie tworzyc DAO dla kazdej z podklas.

0

Możesz po prostu przekazać obiekt typu java.lang.Class, który ma metodę getSimpleName(). Żeby go dostać zastosuj składnię typu Klasa.class, bądź obiekt.getClass().

0

A jak możesz to ort! się na spring data

1

Dla tych co mowia ze sie nie da - czasami sie da wyciagnac typ z generica, ale trzeba troche magii:

abstract class Super<T> {
    final Class<?> clazz;
    Super() {
        clazz = (Class<?>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }
    void blah() {
        System.out.println(clazz);
    }
}
class SubA extends Super<Integer> {}
class SubB extends Super<String> {}
class SubC extends Super<Main> {}

public class Main {

    public static void main(String[] args) {
        new SubA().blah();
        new SubB().blah();
        new SubC().blah();
    }
}

Czasami sie uzywa tego do robienia wlasnie generic dao i podklas, bez potrzeby powtarzania dla jakiego typu dane dao jest tworzone. To dziala tylko i wylacznie w konkretnych podklasach klasy generycznej ktore definiuja parametry. Np. class Sub<T> extends Super<T> nie zadziala (wywali sie w runtime).

0

@niezdecydowany - nie, on napisal ze trzeba miec gdzies pole typu T, nie napisal jak to zrobic. Ja mam pole typu Class<T> ktore automatycznie jest wyciagane w runtime i nie wymaga czegos takiego jak:

class Super<T> {
    Class<T> clazz;
    Super(Class<T> clazz) {
        this.clazz = clazz;
    }
}

class SubA extends Super<Integer> {
    SubA() {
        super(Integer.class); // powtarzanie sie
    }
}

Z innej beczki: nigdzie nie napisalem ze jestem kozak, ja tylko napisalem ze cos sie da i podalem przyklad ktory dziala i pokazuje nie az tak do konca znane mozliwosci refleksji, za co zostalem zaatakowany. Skad ta agresja?

0

Mógłbyś chociaż czytać już udzielone odpowiedzi zamiast kopiować ...

0

A i @niezdecydowany mógłbyś podać alternatywę?

0

Misiaczki o co wy się kłócicie? Pomysł podany przez @the real mućka jest jak najbardziej OK i jest czymś innym niż to o czym wspominałem. Jednocześnie nie jest idealnym rozwiązaniem bo niekoniecznie zadziała dokładnie tak jakbyśmy chcieli (o czym zresztą autor sam wspomniał).

@Świetny Mleczarz jeśli nie chcesz robić osobnego DAO dla każdej podklasy (tzn technicznie rzecz biorąc to byłyby klasy na 1 linijkę kodu bo tylko coś w stylu CośtamDao extends GenericDao<Cośtam> ale jednak ;) ) to będziesz musiał się pobawić w refleksje, innej drogi nie ma.

0

@pomidor: w tym czasie jak ty podales linka to ja pisalem przyklad i nie odswiezylem stronki. Bardzo przepraszam za blad. Nie powiesz jednak, ze wklejony kod jest lepszy niz jakas linijka zakopana gdzies w jakims artykule? Na SO tak sie pisze odpowiedzi, artykul pod linkiem moze zniknac...

@niezdecydowany: widze, ze jednak nie rozumiesz. Wg. ciebie robienei String klasa = "Integer" (swoja droga zle, musi byc java.lang.Integer) w SubA, oraz String klasa = "java.lang.String" w SubB, i taka linijka (statycznie napisana) w kazdej subklasie jest rownoznaczna z wyciaganiem typu raz, w jednym miejscu w klasie bazowej, dynamicznie?

Shalom napisał(a):

jeśli nie chcesz robić osobnego DAO dla każdej podklasy (tzn technicznie rzecz biorąc to byłyby klasy na 1 linijkę kodu bo tylko coś w stylu CośtamDao extends GenericDao<Cośtam> ale jednak ;) ) to będziesz musiał się pobawić w refleksje, innej drogi nie ma.

Mozna jeszcze zrobic jedno DAO i metody parametryzowac z przekazywaniem klasy:

class DAO {
  <T> List<T> getAll(Class<T> clazz, A a, B b) { ... }
}

I tak dla kazdej metody. To sie nazywa runtime type token, opisane lepiej tutaj: https://docs.oracle.com/javase/tutorial/extra/generics/literals.html.
Nadal malo idealne rozwiazanie, ale moze moze...

0

@Mucka spoko

A co do dyskusji, to fajnie jeśli ktoś ma inne zdanie to niech chociaż poda jak to zrobić w inny sposób, a nie takie twierdzenie że czerwony golf jest szybszy bo czerwony

0

Dyskusje prowadzisz Ty, Shalom i ja, pozostali osobnicy trolluja: wywyzaja, obrazaja, uzywaja zwrotow typu 'ssie palke', co za dyskusje nie uwazam.

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