79 votes

Pourquoi l'appel d'une méthode statique via une instance n'est-il pas une erreur pour le compilateur Java?

Je suis sûr que vous le savez tous, le comportement que je veux dire - code comme:

Thread thread = new Thread();
int activeCount = thread.activeCount();

provoque un avertissement du compilateur. Pourquoi n'est-il pas une erreur?

EDIT:

Pour être clair: la question n'a rien à voir avec les Threads. Je me rends compte Thread les exemples sont souvent donnés lors de la discussion de ce en raison du potentiel pour vraiment gâcher les choses avec eux. Mais vraiment, le problème est qu'une telle utilisation est toujours non-sens, et vous ne pouvez pas (compétence) écrire un tel appel et dire que c'. Un exemple de ce type de méthode d'appel serait fou. Voici une autre:

String hello = "hello";
String number123AsString = hello.valueOf(123);

Qui lui donne une apparence comme si chaque instance de Chaîne est livré avec un "String valueOf(int i)" de la méthode.

82voto

Jon Skeet Points 692016

Fondamentalement, je crois que le Java concepteurs fait une erreur quand ils ont conçu la langue, et il est trop tard pour le corriger en raison de la compatibilité des enjeux. Oui, elle peut conduire à de très trompeur code. Oui, vous devriez éviter. Oui, vous devriez assurez-vous que votre IDE est configuré de manière à la traiter comme une erreur, de l'OMI. Si jamais vous la conception d'un langage de vous-même, l'ours à l'esprit, comme un exemple du genre de chose à ne pas faire :)

Juste pour répondre à DJClayworth point, voici ce qui est autorisé en C#:

public class Foo
{
    public static void Bar()
    {
    }
}

public class Abc
{
    public void Test()
    {
        // Static methods in the same class and base classes
        // (and outer classes) are available, with no
        // qualification
        Def();

        // Static methods in other classes are available via
        // the class name
        Foo.Bar();

        Abc abc = new Abc();

        // This would *not* be legal. It being legal has no benefit,
        // and just allows misleading code
        // abc.Def();
    }

    public static void Def()
    {
    }
}

Pourquoi dois-je pense que c'est trompeur? Parce que si je regarde le code someVariable.SomeMethod() - je m'attendre à l'utilisation de la valeur de someVariable. Si SomeMethod() est une méthode statique, que l'attente est invalide; le code est tromper moi. Comment peut éventuellement être une bonne chose?

Bizarrement assez, Java ne vous laissent pas utiliser potentiellement variable non initialisée à l'appel d'une méthode statique, malgré le fait que la seule information dont il va utiliser est le type déclaré de la variable. C'est incohérent et inutile mess. Pourquoi permet-il?

EDIT: Cette modification est une réponse à Clayton réponse, qui prétend qu'il permet à l'héritage pour les méthodes statiques. Il n'a pas. Les méthodes statiques ne sont pas polymorphes. Voici une courte mais complète du programme est de démontrer que:

class Base
{
    static void foo()
    {
        System.out.println("Base.foo()");
    }
}

class Derived extends Base
{
    static void foo()
    {
        System.out.println("Derived.foo()");
    }
}

public class Test
{
    public static void main(String[] args)
    {
        Base b = new Derived();
        b.foo(); // Prints "Base.foo()"
        b = null;
        b.foo(); // Still prints "Base.foo()"
    }
}

Comme vous pouvez le voir, le temps d'exécution de la valeur de b est complètement ignoré.

15voto

Bill the Lizard Points 147311

Pourquoi devrait-il être une erreur? L'instance a accès à toutes les méthodes statiques. Les méthodes statiques ne peuvent pas modifier l'état de l'instance (en essayant de est une erreur de compilation).

Le problème avec l'exemple bien connu que vous donnez est très spécifique pour les threads, pas statique, les appels de méthode. Il semble comme si vous êtes l'obtention de l' activeCount() pour le fil visé par l' thread, mais vous êtes vraiment obtenir le comte pour le thread appelant. C'est une erreur de logique que vous en tant que programmeur sont de décisions. L'émission d'un message d'avertissement est la bonne chose pour le compilateur de faire dans ce cas. C'est à vous de tenir compte de l'avertissement et de corriger votre code.

EDIT: je me rends compte que la syntaxe de la langue est ce qu' permettant de vous écrire trompeuse code, mais n'oubliez pas que le compilateur et ses mises en garde sont une partie de la langue aussi. La langue vous permet de faire quelque chose que le compilateur considère que douteux, mais il vous donne l'avertissement assurez-vous que vous êtes au courant qu'il pourrait causer des problèmes.

12voto

Mehrdad Afshari Points 204872

Parce que la spécification du langage le permet :) Tout comme VB et C # ne le font pas.

10voto

Thilo Points 108673

Ils ne peuvent pas faire une erreur de plus, à cause de tout le code qui est déjà là.

Je suis avec vous sur que ca doit être une erreur. Peut-être il devrait y avoir une option/profil pour le compilateur pour la mise à niveau des mises en garde aux erreurs.

Mise à jour: Quand ils ont introduit le faire valoir de mots clés en 1.4, qui sont similaires à d'éventuels problèmes de compatibilité avec les vieux code, ils l'ont rendu disponible uniquement si vous définissez explicitement le mode de source de "1.4". Je suppose que l'on pourrait faire il une erreur dans un nouveau mode source "java 7". Mais je doute qu'ils le feraient, considérant que tous les tracas que cela causerait. Comme d'autres l'ont souligné, il n'est pas strictement nécessaire pour vous éviter d'écrire du code source de confusion. Et les changements de langue de Java devrait être limitée à l'strictement nécessaire à ce stade.

7voto

PaulJWilliams Points 11641

Réponse courte - la langue le permet, ce n'est donc pas une erreur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X