Tomáš Záluský napsal(a):
Zdravím,
jak bylo psáno, nejde to z důvodu, že generické informace nepřežijí do okamžiku 
běhu programu. Tohle je problém, se kterým generické třídy moc nepomáhají. Aby 
to fungovalo, je třeba příslušný typ mít uložený jako Class object. Takže to 
chce přidat ještě Class do Plugin. Např.


No, nemáte úplně pravdu. Je pravda, že u generické třídy
není informace o aktuálním parametru. Ale u *parametrizované*
třídy tato informace *je*. Protože předpokládám, že bez dívání se
do dokumentace si normální člověk nepamatuje, jaký je v tom rozdíl, osvětlím to.

Generická třída je třeba

class A<T> { }

parametrizovaná třída je třeba

class B extends A<String> {}

tedy parametrizovaná třída má v sobě zakompilovanou informaci, že
je potomkem generické třídy, kde za parametr byla dosazena konkrétní třída.

Jaká to byla se dá zjistit voláním

getGenericSuperclass().getActualTypeArguments()

takže v problému popisovaném panem Beránkem to zdetekovat jde,
až na to, že ten Plugin by nesměl být interface, ale musle by být
abstraktní třída s abtraktní metodou, což snad není zas takový problém.


Tady je modelové řešení, můžete vyzkoušet:

package cz.makub.generika;

import java.lang.reflect.ParameterizedType;

/**
 * Created by IntelliJ IDEA.
 *
 * @author Martin Kuba [EMAIL PROTECTED]
 */
public class Beranek {

    public static abstract class A<T> {
        public void uzijPlugin(String name)  {
            try {
                System.out.println("----");
                System.out.println("plugin: "+name);
                Class c = Class.forName(name);
                Class<T> tClass = (Class<T>) ((ParameterizedType) getClass()
                .getGenericSuperclass()).getActualTypeArguments()[0];
                Class vClass = (Class) ((ParameterizedType) 
c.getGenericSuperclass()).getActualTypeArguments()[0];
                System.out.println("A<"+tClass.getName()+">");
                System.out.println("Plugin<"+vClass.getName()+">");
                if(tClass.equals(vClass)) {
                    System.out.println("jde to");
                } else {
                    System.out.println("nejde to");
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }

        }
    }

    public static abstract class Plugin<V> {
         abstract boolean execute(V param);
    }

    public static class PotomekAStringovy extends A<String> {

        public void delej() {
           uzijPlugin("cz.makub.generika.Beranek$PluginStringovy");
           uzijPlugin("cz.makub.generika.Beranek$PluginIntegerovy");
        }
    }

    public static class PluginStringovy extends Plugin<String> {

        public boolean execute(String param) {
            return false;
        }
    }

    public static class PluginIntegerovy extends Plugin<Integer> {
        public boolean execute(Integer param) {
            return false;
        }
    }

    public static void main(String[] args) {

        PotomekAStringovy pas = new PotomekAStringovy();
        pas.delej();
    }
}

Ty slova static můžete pak odstranit, jenom jsem to chtěl mít všechno
pohromadě v jedné třídě.

Makub

--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Supercomputing Center Brno             Martin Kuba
Institute of Computer Science    email: [EMAIL PROTECTED]
Masaryk University             http://www.ics.muni.cz/~makub/
Botanicka 68a, 60200 Brno, CZ     mobil: +420-603-533775
--------------------------------------------------------------

Reply via email to