Verhalten der endgültigen statischen Methode

Lesezeit: 8 Minuten

Verhalten der endgultigen statischen Methode
Harisch

Ich habe mit Modifikatoren mit statischer Methode herumgespielt und bin auf ein seltsames Verhalten gestoßen.

Wie wir wissen, können statische Methoden nicht überschrieben werden, da sie eher mit Klassen als mit Instanzen verknüpft sind.

Wenn ich also das folgende Snippet habe, wird es gut kompiliert

//Snippet 1 - Compiles fine
public class A {
    static void ts() {
    }
}

class B extends A {
    static void ts() {
    }
}

Aber wenn ich den letzten Modifikator in die statische Methode in Klasse A einfüge, schlägt die Kompilierung fehl
ts() in B kann ts() in A nicht überschreiben; Die überschriebene Methode ist statisch final.

Warum passiert das, wenn die statische Methode überhaupt nicht überschrieben werden kann?

  • Es scheint seltsam, +1 für die Frage, aber bis jetzt ist keine der Antworten zufriedenstellend.

    – Rakesh Juyal

    16. November 09 um 17:54 Uhr

  • Es wird nicht überschrieben. Es ist immer noch da bei A.ts().

    – Alex Feinmann

    16. November 09 um 18:03 Uhr

1643572630 450 Verhalten der endgultigen statischen Methode
NawaMan

Statische Methoden können nicht überschrieben, aber ausgeblendet werden. Der ts() Methode von B überschreibt nicht (nicht Gegenstand von Polymorphismus) die ts() von A, aber es wird es verbergen. Wenn Sie anrufen ts() in B (NICHT A.ts() oder B.ts() … einfach ts()), wird der von B aufgerufen und nicht A. Da dieser nicht dem Polymorphismus unterliegt, wird der Aufruf ts() in A wird nie zu dem in B umgeleitet.

Das Schlüsselwort final verhindert, dass die Methode ausgeblendet wird. Sie können also nicht ausgeblendet werden, und ein Versuch, dies zu tun, führt zu einem Compiler-Fehler.

Hoffe das hilft.

  • Um Ihre Antwort zu beenden, die meiner Meinung nach richtig ist, ist das Problem hier im Grunde eine schlechte Compiler-Fehlermeldung: Sie sollte sagen, dass B nicht kann verbergen ts() in A. Das Deklarieren einer statischen Methode als final bedeutet, dass sie nicht ausgeblendet werden kann.

    – Sean Owen

    16. November 09 um 17:58 Uhr

  • @ Sean Owen: Das denke ich auch. Der Begriff „verbergen“ wird sogar in der Java-Spezifikation verwendet, warum also nicht in der Compiler-Nachricht verwenden?

    – NawaMan

    16. November 09 um 18:10 Uhr

  • Warum ist das überhaupt ein Feature? In welchem ​​Zusammenhang wäre es sinnvoll?

    – Benutzer253751

    25. März 15 um 4:32 Uhr

  • public class Test { final static public void main(String… srik) { System.out.println(“In main method”); ts(); } public static void ts() { Kind c=neues Kind(); c.ts(); System.out.println(“Test ts”); } } public class Child erweitert Test { public static void ts() { System.out.println(“Child ts”); } } Hallo, können Sie mir bitte erklären, was in diesem Szenario passiert?

    – Srikanth r

    20. Februar 16 um 11:14 Uhr

  • Mein Buch “Java How to Program Edition 10” sagt, dass statische Methoden implizit final sind (Kapitel 10.7). prntscr.com/u3too3 Wenn statische Methoden final sind und finale Methoden nicht ausgeblendet werden können. Das bedeutet, dass auch statische Methoden nicht versteckt werden sollten. Aber wir sind in der Lage, statische Methoden zu verstecken.

    – Michael

    22. August 2020 um 2:38 Uhr


Verhalten der endgultigen statischen Methode
Vincent Ramdhanie

statische Methoden können nicht überschrieben werden

Das ist nicht ganz richtig. Der Beispielcode bedeutet wirklich, dass die Methode ts in B die Methode ts in A verbirgt. Es ist also nicht gerade überschreibend. Weiter Javaranch es gibt eine schöne erklärung.

  • Es stimmt nur nicht genau. Statische Methoden können nicht überschrieben, aber ausgeblendet werden, wenn Sie sie für eine Instanzreferenz statt für den Klassennamen aufrufen.

    – John Mercier

    26. Februar 15 um 15:09 Uhr

  • Leider funktioniert dein Link nicht mehr. Ist es möglich, dies zu beheben?

    – Matthias Bader

    12. September 17 um 11:54 Uhr

  • Der Javaranch-Link funktioniert nicht, aber das Googeln der Schlüsselwörter ist aufgetaucht dieser Link auf Coderanch

    – Sundeep

    28. November 18 um 14:34 Uhr

  • Ich habe den Beitrag bearbeitet, indem ich den toten Link durch den von Sundeep geposteten Link ersetzt habe.

    – MC Kaiser

    17. Mai 19 um 11:54 Uhr

1643572631 774 Verhalten der endgultigen statischen Methode
Machtherr

Statische Methoden gehören zur Klasse, nicht zur Instanz.

A.ts() und B.ts() werden immer getrennte Methoden sein.

Das eigentliche Problem besteht darin, dass Sie mit Java statische Methoden für ein Instanzobjekt aufrufen können. Statische Methoden mit der gleichen Signatur aus der übergeordneten Klasse sind versteckt wenn es von einer Instanz der Unterklasse aufgerufen wird. Sie können jedoch nicht überschreiben/ausblenden endgültige Methoden.

Sie würden denken, die Fehlermeldung würde das Wort versteckt statt überschrieben verwenden …

Verhalten der endgultigen statischen Methode
Matthias Bader

Möglicherweise befinden Sie sich in der Position, darüber nachzudenken, eine statische Methode endgültig zu machen, wenn Sie Folgendes berücksichtigen:

Folgende Klassen haben:

class A {
    static void ts() {
        System.out.print("A");
    }
}
class B extends A {
    static void ts() {
        System.out.print("B");
    }
}

Nun wäre der ‘richtige’ Weg, diese Methoden aufzurufen

A.ts();
B.ts();

was dazu führen würde AB Sie könnten die Methoden aber auch für Instanzen aufrufen:

A a = new A();
a.ts();
B b = new B();
b.ts();

was dazu führen würde AB sowie.

Betrachten Sie nun Folgendes:

A a = new B();
a.ts();

das würde drucken A. Das mag Sie überraschen, da Sie tatsächlich ein Objekt der Klasse haben B. Aber da Sie es von einer Referenz des Typs aufrufen A, wird es anrufen A.ts(). Sie könnten drucken B mit folgendem Code:

A a = new B();
((B)a).ts();

In beiden Fällen stammt das Objekt, das Sie haben, tatsächlich aus der Klasse B. Aber abhängig von dem Zeiger, der auf das Objekt zeigt, rufen Sie die Methode von auf A oder von B.

Nehmen wir nun an, Sie sind der Entwickler der Klasse A und Sie Unterklassen zulassen möchten. Aber Sie wollen wirklich Methode ts(), wann immer es aufgerufen wird, selbst von einer Unterklasse, das heißt, es tut, was Sie wollen, und nicht von einer Unterklassenversion versteckt zu werden. Dann könntest du es schaffen final und verhindern, dass es in der Unterklasse versteckt wird. Und Sie können sicher sein, dass der folgende Code die Methode aus Ihrer Klasse aufruft A:

B b = new B();
b.ts();

Ok, das ist zugegebenermaßen irgendwie konstruiert, aber für manche Fälle mag es Sinn machen.

Sie sollten statische Methoden nicht auf Instanzen aufrufen, sondern direkt auf den Klassen – dann haben Sie dieses Problem nicht. Auch IntelliJ IDEA zum Beispiel zeigt Ihnen eine Warnung, wenn Sie eine statische Methode auf einer Instanz aufrufen und wenn Sie eine statische Methode final machen.

Die ts()-Methode in B überschreibt nicht die ts()-Methode in A, es ist einfach eine andere Methode. Die B-Klasse sieht die ts()-Methode in A nicht, da sie statisch ist, daher kann sie ihre eigene Methode namens ts() deklarieren.

Wenn die Methode jedoch final ist, erkennt der Compiler, dass es in A eine ts()-Methode gibt, die in B nicht überschrieben werden sollte.

  • Ich glaube nicht, dass dies erklärt, warum „endgültig“ plötzlich bedeutet, dass diese Methoden nicht koexistieren können. Wie Sie sagen, ohne “final” gibt es kein Problem. Sie sagen, es überschreibt nicht, aber dann sagen Sie, das Problem sei, dass B die Methode von A nicht überschreiben kann.

    – Sean Owen

    16. November 09 um 17:55 Uhr

  • Sicher, ich behaupte, dass B die Methode ts() in A nicht sieht (sie ist ‘versteckt’), aber der letzte Modifikator ‘versteckt’ keine Methoden vor Klassen, die eine andere erweitern. Aber äh, ok.

    – Unfug

    16. November 09 um 18:03 Uhr

  • Ich denke, vielleicht könnte Ihre Formulierung “sollte nicht in B überschrieben werden” in “sollte nicht in B ausgeblendet werden” geändert werden.

    – Scratte

    17. September 2020 um 10:02 Uhr

1643572631 153 Verhalten der endgultigen statischen Methode
BalusC

Ich denke, der Kompilierungsfehler war hier ziemlich irreführend. Es hätte nicht sagen sollen “überschriebene Methode ist statisch final.”, sondern stattdessen “überschriebene Methode ist final.”. Der statische Modifikator spielt hier keine Rolle.

  • Ich glaube nicht, dass dies erklärt, warum „endgültig“ plötzlich bedeutet, dass diese Methoden nicht koexistieren können. Wie Sie sagen, ohne “final” gibt es kein Problem. Sie sagen, es überschreibt nicht, aber dann sagen Sie, das Problem sei, dass B die Methode von A nicht überschreiben kann.

    – Sean Owen

    16. November 09 um 17:55 Uhr

  • Sicher, ich behaupte, dass B die Methode ts() in A nicht sieht (sie ist ‘versteckt’), aber der letzte Modifikator ‘versteckt’ keine Methoden vor Klassen, die eine andere erweitern. Aber äh, ok.

    – Unfug

    16. November 09 um 18:03 Uhr

  • Ich denke, vielleicht könnte Ihre Formulierung “sollte nicht in B überschrieben werden” in “sollte nicht in B ausgeblendet werden” geändert werden.

    – Scratte

    17. September 2020 um 10:02 Uhr

1643572632 761 Verhalten der endgultigen statischen Methode
Pratik Gupta

Eine statische Methode kann in Java im Gegensatz zu nicht statischen Methoden nicht überschrieben werden. Aber sie werden wie statische und nicht statische Datenelemente vererbt. Aus diesem Grund kann in der übergeordneten Klasse keine nicht statische Methode mit demselben Namen erstellt werden

class Writer { 
    public static void doo(){
        System.out.println("sth");
    } 
}
class Author extends Writer{ 
    public void doo(){
        System.out.println("ok"); // error overridden method is static
    }
}

Der final Das Schlüsselwort stellt sicher, dass der spezifische Methodentext bei jedem Aufruf der Methode ausgeführt wird. Wenn nun in der untergeordneten Klasse eine gleichnamige statische Methode erstellt und die Methode aufgerufen wird, wird die Methode in der Unterklasse ausgeführt, was nicht der Fall sein sollte, wenn final vor dem Namen der statischen Methode in der übergeordneten Klasse vorangestellt wird . Daher schränkt das Schlüsselwort final die Erstellung von Methoden mit demselben Namen in der untergeordneten Klasse ein.

  • “Aber sie werden wie statische und nicht statische Datenelemente vererbt.” Das glaub ich nicht. Sie sind zugänglich von der untergeordneten Klasse, aber das ist nicht dasselbe wie geerbt. “Das Schlüsselwort final schränkt die Erstellung einer Methode mit demselben Namen in der untergeordneten Klasse ein.” ist auch nicht richtig. Sie können eine statische final-Methode in einer untergeordneten Klasse überladen. Sie können einfach keine Methode mit derselben Signatur erstellen.

    – Scratte

    17. September 2020 um 9:56 Uhr


.

705080cookie-checkVerhalten der endgültigen statischen Methode

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

Privacy policy