2 Stimmen

Java-Generik-Hysterie

Kann mir jemand bei diesen Generika helfen?

Wenn man eine überladene Methode mit verschiedenen Typen hat, die ein Argument sein können, kann man eine generische Methode schreiben, die zur Laufzeit die richtige aufruft? (Tut mir leid, wenn meine Java-Kenntnisse schlecht sind, falls ja)

Beispiel:

public interface CoolInterface {
   setOverloadedValue(String o);
   setOverloadedValue(Integer o);
   setOverloadedValue(Date o);
}

public interface ClazzProvider {
   Class getClazz();
}

public class SomeUncoolClass {

   @AutowiredMagic CoolInterface coolGuy;
   @AutowiredMagic ClazzProvider clazzyProvider;

   public void helpMeMethod() {
      coolGuy.setOverloadedValue(getValue(clazzyProvider.getClazz()));
   }

   private ??? getValue(???) {
      return ???;
   }
}

Wie lautet die Methodensignatur von getValue()? Und wie kann ich sie implementieren?

6voto

Jon Skeet Punkte 1325502

Nein - die Überladung wird zur Kompilierzeit ausgewählt, und der Compiler kann nicht erkennen, welche Überladung Sie verwenden möchten.

Schauen Sie sich doch einmal die Besucher-Muster als Workaround für den Fall, dass die Typen, die Sie akzeptieren wollen, unter Ihrer Kontrolle sind - es hilft allerdings nicht viel, wenn Sie String/Date/Object akzeptieren wollen :(

2voto

Arne Burmeister Punkte 19217

Ich bin mir nicht sicher, was die Absicht dieses Codes ist, aber vielleicht wollen Sie so etwas wie dies:

public interface CoolInterface<T> {
   void setOverloadedValue(T o);
}

public interface ValueProvider<T> {
   T getValue();
}

public class SomeUncoolClass<T> {

   private CoolInterface<? super T> coolGuy;
   private ValueProvider<? extends T> valueProvider;

   public void helpMeMethod() {
      coolGuy.setOverloadedValue(valueProvider.getValue());
   }
}

1voto

polygenelubricants Punkte 362173

Sie können etwas Ähnliches mit dem erreichen, was Joshua Bloch in Effective Java 2nd Edition einen typesafe heterogenous container (THC) nennt.

import java.util.*;

class TypesafeHeterogenousContainer {
    Map<Class<?>, Object> map = new HashMap<Class<?>, Object>();

    public <T> T get(Class<T> klass) {
        return klass.cast(map.get(klass));
    }

    public <T> void put(Class<T> klass, T thing) {
        map.put(klass, thing);
    }
}

public class Main {
    public static void main(String args[]) {
        TypesafeHeterogenousContainer thc = new TypesafeHeterogenousContainer();
        thc.put(String.class, "a string");
        thc.put(Integer.class, 5);
        System.out.println(thc.get(String.class)); // prints "a string"

        thc.put(String.class, 5); // compile-time error
    }
}

Dies geschieht nicht gerade durch Überladen, denn das ist unmöglich, da Java generics type-erasure verwendet. Also müssen Sie stattdessen Class<?> Objekte zur Laufzeit.

Sie können mehr darüber im Buch oder auf einigen anderen Seiten im Internet lesen.

Wenn Sie das Buch nicht haben, können Sie es in seinem Vortrag auf der Java One 2006 nachlesen PDF .

1voto

helios Punkte 13224

Wie Jon Skeet sagte, werden Generika in diesem Fall nicht helfen.

Sie könnten sich das Besuchermuster ansehen, das in einigen Situationen hilft, in denen polimorphe Paramenter unterschiedliche Methodenausführungen benötigen. Aber VORSICHT: Es hilft nur, wenn die Typenhierarchie stabil ist.

Wenn Sie eine generische Verarbeitung mit einer instabilen Liste von Typen wünschen oder Ihnen die Komplexität des Besuchermusters nicht gefällt, empfehle ich eine Map<Class, ValueProcessor> :

private [static?] Map<Class, ValueProcessor> processors = new HashMap<Class, ValueProcessor>();

// initialization
processors.put(Integer.class, new ValueProcessor() {
   public void process(Object value) {
      doStuffWith( (Integer) value);
   }
});

processors.put(Date.class, new ValueProcessor() {
   public void process(Object value) {
      doStuffWith( (Date) value);
   }
});

// and so on...

public interface ValueProcessor {
   public void process(Object value);
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X