Frage

Ist es möglich, eine Methode, bei der entweder Classa oder InterfaceB akzeptiert werden?

Kompiliert nicht aufgrund von | Pseudocode

public <T extends Number | CharSequence> void orDoer(T someData){ // ... }

IE, anstatt mehrere Methodensignaturen zu schreiben, möchte ich, dass diese eine Methode entweder eine Nummer oder eine charsequenz als Argument akzeptiert

Sollte mit einer Nummer oder einem Charse -Argument passieren

orDoer(new Integer(6));
int somePrimitive = 4;
orDoer(somePrimitive);
orDoer("a string of chars");
War es hilfreich?

Lösung

Wenn du Ja wirklich Wenn Sie dies tun möchten, müssen Sie Sie angenommene Klassen in eine eigene Klasse einwickeln. In Ihrem Beispielfall wahrscheinlich so etwas wie:

public class OrDoerElement {
    private final Number numberValue;
    private final CharSequence charSequenceValue;

    private OrDoerElement(Number number, CharSequence charSequence) {
        this.numberValue = number;
        this.charSequenceValue = charSequence;
    }

    public static OrDoerElement fromCharSequence(CharSequence value) {
        return new OrDoerElement(null, value);
    }

    public static OrDoerElement fromNumber(Number value) {
        return new OrDoerElement(value, null);
    }
}

Und dein orDoer Methode wird:

public void orDoer(OrDoerElement someData) { .... }

Dann können Sie eine davon erstellen und in Ihrer Methode verwenden, indem Sie entweder:

orDoer(OrDoerElement.fromCharSequence("a string of chars"));
orDoer(OrDoerElement.fromNumber(new Integer(6)));

Aber ehrlich gesagt klingt das etwas zu komplex und zu viel Arbeit, nur um eine Methode mit verschiedenen Parametertypen aufrufen zu können. Sind Sie sicher, dass Sie mit zwei Methoden und einer dritten Methode für die gemeinsame Logik nicht dasselbe erreichen können?

Andere Tipps

Verwendet eine anonyme abstrakte Klasse eine Option für Sie? Wenn ich type sichere Parameter oder Rückgabetypen benötige, verwende ich eine Variante des folgenden Codes. Davon abgesehen stimme ich den anderen Kommentaren hier zu und bin neugierig, welchen Vorteil Sie wirklich abgeben, wenn Sie eine Art Sicherheit für eine Gruppe von Objekten durchsetzen, die nicht so viel gemeinsam haben.

public abstract class Doer<T> {

  public void do(T obj) {
    // do some stuff. 
  }

}

// calling method

new Doer<Number>(){}.do(new Integer(5));

Für die ursprüngliche Frage:

public void orDoer(Object someData){
    assert someData instanceof Number || someData instanceof CharSequence;

    // ...
}

In Ihrem spezifischeren Fall die assert Die Aussage sollte nur die Selbstbekämpfung verwenden, um zu klären, ob das Objekt über die gewünschten Besonderheiten verfügt, dh nach einem Konstruktor von String, Sonde, um eine neue Instanz des Objekts aus dem zu erstellen toString() Ergebnis des eingehenden Objekts und vergleichen Sie beide für Gleichheit:

public void orDoer(Object someData) {
    assert isUniconstructable(someData);
}

public static boolean isUniconstructable(Object object) {
    try {
        return object.equals(object.getClass().getConstructor(String.class)
            .newInstance(object.toString()));
    } catch (InstantiationException | IllegalAccessException | InvocationTargetException
            | NoSuchMethodException| RuntimeException e) {
        return false;
    }
}

(Aufgrund der Ausnahmen, die möglicherweise geworfen werden können, müssen wir den Assert -Test in seine eigene Funktion einwickeln.)

Beachten Sie diese Selbstbeobachtung kann Brechen Sie aufgrund von Androids Proguard -Code -Komprimierung, die die Klassennamen umschreibt, und anstelle von YourClass Nur eine Klasse, dh Q, wird in der Datenbank gespeichert und wenn Sie sie mit einer späteren Version Ihrer App wiederherstellen möchten, die über mehr Klassen verfügt, Klasse, Klasse Q ist dann etwas anderes. Weitere Informationen hierzu finden Sie auf der Proguard -Website. Ich wollte nur benachrichtigen, dass Sie sich dessen bewusst sein sollten, wenn Sie die Selbstbeobachtung auf Android verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top