Bestimmung der Menge aller Supertypen eines Typs

Genau, daß geht aber auch mit Generatoren. Als Ergebnis erhält man wiederum einen Generator, der eben die Schnittmenge erhält anstatt eine konkrete Menge.

Die Implementierung dazu ist einfacher als man anfangs vermuten mag.
Grundvoraussetzung ist dafür nur dass man ein Comparable Interface implementiert bekommt.

Aber es gibt halt auch ein paar Spezialfälle die es zu erkennen gilt.
z.B. Beide Mengen unbeschränkt & Schnittmenge == Leere Menge
Beide Mengen unbeschränkt & Schnittmenge == eine beschränkte Menge

Aber oftmals reicht es, wie bei PI, nur näherungsweise an ein Ergebnis zu kommen.

Nun, wie gesagt, „notwendig“ ist das ganze nicht, und so ein „Generator“ wäre nicht das, was ich wollte, aber … nur mal hypothetisch: Das ganze setzt zumindest zwingend eine Ordnung voraus. Ansonsten hat man ein Element, und muss prüfen, ob das in der anderen Menge enthalten ist … … …

EDIT: Ja, das hast du schon gesagt (ich sollte um diese Uhrzeit nicht mehr antworten :o ) aber… wie würde diese Ordnung denn aussehen? Es gibt zumindest keine totale Ordnung auf den Typen. Spätestens durch Interfaces ist die „nahe liegende“ Ordnung nur partiell… dazu ein snippet aus einer anderen Lib (Reflection-Utilities), die ich für das eigentliche Programm bastel(t)e:

    /**
     * Returns whether the given class is maximal for the given sequence
     * of classes. Note that the inheritance hierarchy of classes is 
     * only a partial order. For a subset S of a partially ordered set, 
     * an element <code>m</code> is maximal iff
     * <code>
     * forEach (s in S) . m <= s -> m = s
     * </code>
     * This method checks the given class strictly according to this 
     * definition. Thus, a given class <code>c</code> is <i>maximal</i> for  
     * the given sequence of classes, if there is no subclass of <code>c</code>  
     * in the given sequence that is not equal to <code>c</code> itself. 
     * Particularly, there may be multiple <i>maximal</i> elements in one 
     * sequence!
     *  
     * @param c The class which is about to be checked
     * @param sequence The sequence of classes for which the given class
     * must be maximal 
     * @return Whether the given class is maximal for the given sequence
     * of classes. 
     */
    private static boolean isMaximal(
        Class<?> c, Iterable<? extends Class<?>> sequence)
    {
        for (Class<?> other : sequence)
        {
            if (!c.equals(other) && c.isAssignableFrom(other))
            {
                return false;
            }
        }
        return true;
    }

:wink:

“c.equals(other)”? Noch macht das keinen Sinn, weil “Class” “equals()” nicht überschreibt, aber was nicht ist kann ja noch kommen. Von daher sollte “if(!c.isAssignableFrom(other))” vollkommen ausreichen… wenn ich wüsste, was du vorhast… Vom Quelltext her übernimmt diese Aufgabe ja eigentlich der Compiler. Bei den “???” im Quiz können also die Typen Object, Serializable, Comparable<?>, Comparable<? extends Number> und Comparable (Comparable<? extends Integer> sogar auch :kopfkratz:) sowie die Primitivtypen int, long, double und float stehen (Primitivtypen logischerweise nur wenn AutoIn-Outboxing aktiv ist). Herauszufinden, welche Generics nun im weiteren Programmverlauf an Stelle der Fragezeichen rücken dürfen, kann dir nicht mal der Compiler sagen, weswegen man manchmal auch nicht um dieses dämliche “SupressWarnings” drum rum kommt.

Man könnte auch == schreiben, aber … ich wüßte kaum, wie und warum man Grenzfälle, wie dass dieselbe Klasse zweimal geladen wird, behandeln sollte.

Die gepostete Methode gibt aus, ob eine Klasse bezüglich einer Menge von anderen Klassen maximal ist. Wie und wo man da “if(!c.isAssignableFrom(other))” verwenden sollte (und warum das reichen sollte) erschließt sich mir nicht ganz. Die Methode ist übrigens Teil der Suche nach der “Most Specific Method”, entsprechend der http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2.5 . Man muss überprüfen, ob bei mehreren Methoden, die zu den übergebenen Argumenten passende Interface-Parametertypen haben, eine spezifischste existiert. Also bei

interface A0 { }
interface A1 //extends A0
{ }
interface B extends A0, A1 { }

class Foo {
    void method(A0 a) { }
    void method(A1 a) { }


    public static void main(String args[]) {
        Foo foo = null;
        B b = null;
        foo.method(b);
    }
}

ist beim Aufruf von foo.method(b) nicht klar, welche Methode aufgerufen werden soll. Wenn man aber das auskommentierte ‘extends A0’ reinnimmt, ist es klar - nämlich die, die spezifischer ist. Und OB so eine spezifischste existiert, kann man bestimmen, indem man überprüft, ob es genau eine Methode gibt, bei denen alle Parameter die größten sind (also es nur einen maximalen Parameter gibt) (aber nur, wenn ansonsten schon alle anderen Fragen geklärt sind - diese Abfrage kommt ganz am Schluss…)

Bzgl. des Quizzes: Majora hatte es ja schon gesagt: Es gibt unendlich viele Möglichkeiten.
Comparable<? extends Integer>
Comparable<? extends Comparable<? extends Integer>>
Comparable<? extends Comparable<? extends Comparable<? extends Integer>>>

Dann willst du also nur feststellen, das “c” nicht in “sequence” vorhanden ist (also genau das Gegenteil von dem, was ich gedacht habe)? Ok, dann eben doch “if(c != other && c.isAssignableFrom(other)”. Aber “equals()” hilft dir auch bei doppelt geladenen Klassen nicht, weil “.equals()” nun mal “==” bedeutet.

Ja, das hätte ich wohl klarer schreiben sollen: Das equals entspricht ==, und eigentlich bringt es nichts, equals statt == zu verwenden - aber … Referenztypen vergleicht man üblicherweise eben mit equals…
Ob c in der Menge enthalten ist, spielt eigentlich keine Rolle. Das ist ja nur die Ausimplementierung der Definition von “Maximum”:
max(m) <-> forEach(s) . m<=s -> m=s <=>
!max(m) <-> exists(s) . -(m<=s -> m=s) <=>
!max(m) <-> exists(s) . -(-m<=s v m=s) <=>
!max(m) <-> exists(s) . m<=s ^ m!=s
Aber das driftet schon ein bißchen vom ursprünglichen Thema ist. Ich glaube, der Punkt, dass es auf Klassen keine totale Ordnung gibt, steht außer Frage.