Wie mache ich eine generische Java-Methode statisch?

Lesezeit: 7 Minuten

Das Folgende ist ein Ausschnitt darüber, wie man eine generische Java-Klasse erstellt, um ein einzelnes Element an ein Array anzuhängen. Wie kann ich appendToArray zu einer statischen Methode machen. Das Hinzufügen von static zur Methodensignatur führt zu Kompilierungsfehlern.

public class ArrayUtils<E> {

        public E[] appendToArray(E[] array, E item) {
            E[] result = (E[])new Object[array.length+1];
            result[array.length] = item;
            return result;
        }
}

  • Welche Kompilierungsfehler erhalten Sie? Und warum nicht einfach einen der Standard-Bibliothekscontainer verwenden?

    – Karl Knechtel

    10. Dezember 2010 um 13:08 Uhr


  • Kompilierungsfehler: Ich habe den statischen Modifikator tatsächlich falsch hinzugefügt. Verwendung von Sammlungen: Ja, die Verwendung einer Sammlung wäre ideal, aber die Frage bezieht sich nicht auf Sammlungen im Vergleich zu Arrays, mein Anwendungsfall erfordert ein Array.

    – Chris Johnson

    10. Dezember 2010 um 13:30 Uhr

  • Beachten Sie, dass Sie (EVIL) Reflection verwenden müssen, um zu verhindern, dass Clientcode unter einigen, aber nicht allen Umständen eine Ausnahme auslöst (nett). Referenzarrays sollten am besten vermieden werden.

    – Tom Hawtin – Angelleine

    10. Dezember 2010 um 14:26 Uhr


Benutzer-Avatar
Cheffeld

Das einzige, was Sie tun können, ist, Ihre Signatur zu ändern

public static <E> E[] appendToArray(E[] array, E item)

Wichtige Details:

Generische Ausdrücke, die dem Rückgabewert vorangestellt sind, führen (deklarieren) immer eine neue generische Typvariable ein.

Geben Sie außerdem Variablen zwischen den Typen ein (ArrayUtils) und statische Methoden (appendToArray) stören sich nie gegenseitig.

Also, was bedeutet das: In meiner Antwort <E> würde die verstecken E aus ArrayUtils<E> wenn die Methode nicht wäre static. UND <E> hat nichts damit zu tun E aus ArrayUtils<E>.

Um diese Tatsache besser widerzuspiegeln, wäre eine korrektere Antwort:

public static <I> I[] appendToArray(I[] array, I item)

  • Bitte beachten Sie auch, dass es absolut keine Beziehung zwischen der Typvariablen auf Klassenebene gibt E und die statische Methodentypvariable E. Ich halte es für viel besser, einen anderen Variablennamen zu verwenden, wenn generische Methoden, statische oder andere, innerhalb generischer Klassen deklariert werden.

    – Richter Mental

    4. Oktober 2013 um 3:34 Uhr


  • aber in diesem Fall kann ich ein Objekt unterschiedlichen Typs in die Params übergeben. Wie ich Integer übergeben kann[] Array als erster Parameter und Double-Element.

    – Pinker Panther

    20. Mai 2015 um 8:50 Uhr


  • pinkpanther: Stimmt, schadet aber nicht, weil die statische Methode immer nur auf einem Array-Objekt operiert, das ihr per Parameter übergeben wird, also dessen Elemente sicher den richtigen Typ haben.

    – Dabbler

    22. August 2016 um 19:19 Uhr

Benutzer-Avatar
Bert F

public static <E> E[] appendToArray(E[] array, E item) { ...

Beachten Sie das <E>.

Statische generische Methoden benötigen ihre eigene generische Deklaration (public static <E>) getrennt von der generischen Deklaration der Klasse (public class ArrayUtils<E>).

Wenn sich der Compiler über eine Typmehrdeutigkeit beim Aufrufen einer statischen generischen Methode beschwert (wieder in Ihrem Fall nicht wahrscheinlich, aber im Allgemeinen nur für den Fall), erfahren Sie hier, wie Sie explizit eine statische generische Methode mit einem bestimmten Typ aufrufen (_class_.<_generictypeparams_>_methodname_):

String[] newStrings = ArrayUtils.<String>appendToArray(strings, "another string");

Dies würde nur passieren, wenn der Compiler den generischen Typ nicht bestimmen kann, weil zB der generische Typ nicht mit den Methodenargumenten zusammenhängt.

  • Wie kann ich diese statische Methode importieren?

    – ohneEins

    22. April um 10:00 Uhr

Benutzer-Avatar
Vishnu Vivek

Ich werde es auf einfache Weise erklären.

Auf Klassenebene definierte Generika sind vollständig getrennt von den auf (statischer) Methodenebene definierten Generika.

class Greet<T> {

    public static <T> void sayHello(T obj) {
        System.out.println("Hello " + obj);
    }
}

Wenn Sie den obigen Code irgendwo sehen, beachten Sie bitte, dass das auf Klassenebene definierte T nichts mit dem in der statischen Methode definierten T zu tun hat. Der folgende Code ist ebenfalls vollständig gültig und entspricht dem obigen Code.

class Greet<T> {

    public static <E> void sayHello(E obj) {
        System.out.println("Hello " + obj);
    }
}

Warum muss die statische Methode ihre eigenen Generika haben, die von denen der Klasse getrennt sind?

Dies liegt daran, dass die statische Methode aufgerufen werden kann, ohne die Klasse zu instanziieren. Wenn also die Klasse noch nicht instanziiert ist, wissen wir noch nicht, was T ist. Aus diesem Grund müssen die statischen Methoden ihre eigenen Generika haben.

Wenn Sie also die statische Methode aufrufen,

Greet.sayHello("Bob");
Greet.sayHello(123);

JVM interpretiert es wie folgt.

Greet.<String>sayHello("Bob");
Greet.<Integer>sayHello(123);

Beide geben die gleichen Ausgänge.

Hello Bob
Hello 123

Sie müssen den Typparameter auf die Methodenebene verschieben, um anzugeben, dass Sie eine generische Methode und keine generische Klasse haben:

public class ArrayUtils {
    public static <T> E[] appendToArray(E[] array, E item) {
        E[] result = (E[])new Object[array.length+1];
        result[array.length] = item;
        return result;
    }
}

Wie kann ich appendToArray zu einer statischen Methode machen?

Um es statisch zu machen, müssen Sie:

  • Ergänzen Sie die static Modifikator
  • fügen Sie den generischen Typ hinzu E zur Methodensignatur

Speziell für Ihr Beispiel bedeutet dies, die Methodensignatur von dieser zu ändern:

public E[] appendToArray(E[] array, E item) {

dazu:

// same as above, but with "static <E>" before return type E[]
public static <E> E[] appendToArray(E[] array, E item) {

Das Schlüsselelement, das leicht zu übersehen ist: Der generische Typ sollte der Signatur hinzugefügt werden und nur erscheinen Vor der Rückgabetyp. Auszug unten aus dem Java-Tutorial auf Generische Methoden:

Generische Methoden sind Methoden, die ihre eigenen Typparameter einführen. Dies ähnelt der Deklaration eines generischen Typs, aber der Geltungsbereich des Typparameters ist auf die Methode beschränkt, in der er deklariert wird. Statische und nichtstatische generische Methoden sowie generische Klassenkonstruktoren sind erlaubt.

Die Syntax für eine generische Methode enthält eine Liste von Typparametern in spitzen Klammern, die vor dem Rückgabetyp der Methode angezeigt wird. Bei statischen generischen Methoden muss der Typparameterabschnitt vor dem Rückgabetyp der Methode erscheinen.

Benutzer-Avatar
Doktor

Von javadoc

Generische Methoden

Generische Methoden sind Methoden, die ihre eigenen Typparameter einführen. Dies ähnelt der Deklaration eines generischen Typs, aber der Geltungsbereich des Typparameters ist auf die Methode beschränkt, in der er deklariert wird. Statische und nichtstatische generische Methoden sowie generische Klassenkonstruktoren sind erlaubt.

Die Syntax für eine generische Methode enthält eine Liste von Typparametern in spitzen Klammern, die vor dem Rückgabetyp der Methode angezeigt wird. Bei statischen generischen Methoden muss der Typparameterabschnitt vor dem Rückgabetyp der Methode erscheinen.

Die Util-Klasse enthält eine generische Methode, Compare, die zwei Pair-Objekte vergleicht:

public class Util {
    public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
        return p1.getKey().equals(p2.getKey()) &&
               p1.getValue().equals(p2.getValue());
    }
}


public class Pair<K, V> {

private K key;
private V value;

public Pair(K key, V value) {
    this.key = key;
    this.value = value;
}

public void setKey(K key) { this.key = key; }
public void setValue(V value) { this.value = value; }
public K getKey()   { return key; }
public V getValue() { return value; }
}

Die vollständige Syntax zum Aufrufen dieser Methode wäre:

Pair<Integer, String> p1 = new Pair<>(1, "apple");
Pair<Integer, String> p2 = new Pair<>(2, "pear");
boolean same = Util.<Integer, String>compare(p1, p2);

Der Typ wurde explizit angegeben, wie fett dargestellt. Im Allgemeinen kann dies weggelassen werden und der Compiler leitet den Typ ab, der benötigt wird:

Pair<Integer, String> p1 = new Pair<>(1, "apple");
Pair<Integer, String> p2 = new Pair<>(2, "pear");
boolean same = Util.compare(p1, p2);

Diese als Typrückschluss bezeichnete Funktion ermöglicht es Ihnen, eine generische Methode als gewöhnliche Methode aufzurufen, ohne einen Typ zwischen spitzen Klammern anzugeben.

Nachdem Sie dieses Dokument verstanden haben, lautet die Antwort auf Ihre Frage:

public static <I> I[] appendToArray(I[] array, I item)

1354400cookie-checkWie mache ich eine generische Java-Methode statisch?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy