2009-08-21 12 views
3

Wenn ich habe folgendes:Was könnte beim Aufruf einer statischen Methode mit einem Objekt in Java schief gehen?

class A { 
    public A() { } 
    public static void foo() { System.out.println("foo() called"); } 
} 

public class Main { 
    public static void main(String [] args) { 
    A a = new A(); 
    a.foo(); // <-- static call using an instance. 
    A.foo(); // <-- static call using class 
    } 
} 

es irgendwelche Probleme gibt, die den Aufruf von foo() mit einer Instanz auftreten können? Behandelt die JVM den ersten Aufruf von foo() genau wie eine statische Methode oder gibt es eine gewisse technische Feinheit?

Antwort

8

Es ist sehr einfach, subtile Logikfehler einzuführen, indem statische Methoden von Instanzen aufgerufen werden. Typischer Fall, dies nicht tun, was Sie denken, es tut:

Thread t = new Thread(...); 
t.sleep(1000); 

sleep ist eine statische Methode, die den aktuell ausgeführten Thread pausiert, nicht die Thread-Instanz.

2

Die beiden Anrufe sind gleich. Das Problem, das in den Sinn kommt, ist, dass beim Überschreiben von Klasse A foo() nicht direkt überschrieben werden kann.

0

Nicht 100% sicher, aber Sie riskieren möglicherweise eine Nullzeigerausnahme, wenn Ihre Instanz null ist.

+4

das ist ein guter Punkt. Seltsamerweise, wenn ich gerade Ihre Hypothese getestet habe, arbeitet es * an einer Nullreferenz. –

+1

Die Instanz kann null sein und die statische wird korrekt ausgeführt. – doomspork

+0

Ja, deshalb sagte ich, ich sei mir nicht sicher. Die VM muss intelligent genug sein, um die Funktion von der Klasse anstelle der Instanz zu erhalten. – patros

1

Es gilt nur als schlechte Form/Praxis. Vermeiden Sie dies.

+0

Vielleicht könnten Sie etwas genauer erklären, warum diese Praxis entwickelt wurde? –

+0

Julias Antwort fasst ziemlich genau zusammen, warum es schlecht ist - es ist verwirrend. –

1

Ein guter Grund ist, dass Sie andere Leute verwirren können, die Ihren Code lesen oder aktualisieren müssen. Es scheint wirklich, als ob das instanziierte Objekt an dem Methodenaufruf beteiligt sein sollte, obwohl es in Wirklichkeit gar nicht existiert (und tatsächlich null sein kann). Es ist eine unnötige Verschleierung.

Verwandte Themen