Double Possible:
Java: la Justification de la classe de l'Objet n'étant pas déclarée abstractPourquoi est la classe de l'Objet, qui est la classe de base de 'em all en Java, pas de résumé?
J'ai eu cette question depuis très très longtemps, et il est demandé ici par pure curiosité, c'est tout. Rien dans mon code ou le code de personne, c'est de casser car il n'est pas abstrait, mais je me demandais pourquoi ils l'ont fait en béton?
Pourquoi quelqu'un voudrait-il une "instance" (et non pas de sa présence.k.un. De référence) de cette classe d'Objet? Un cas est une mauvaise synchronisation de code qui utilise l'instance d'un Objet de verrouillage (au moins je l'ai utilisé de cette façon une fois.. mon mauvais).
Est-il de l'utilisation pratique d'une "instance" d'un Objet de la classe? Et comment son instanciation d'ajustement de la programmation orientée objet? Ce qui se serait passé s'ils avaient marqué un niveau abstrait (bien entendu, après en fournissant des implémentations de ses méthodes)?
Réponses
Trop de publicités?Sans les concepteurs de l' java.lang.Object
de nous dire, nous avons à la base de nos réponses sur l'opinion. Il y a quelques questions qui peuvent être posées qui peuvent aider à clarifier les choses.
Serait l'une des méthodes de l'Objet bénéficier de l'abstrait?
On pourrait faire valoir que certaines méthodes pourraient en bénéficier. Prendre en hashCode()
et equals()
par exemple, il y aurait probablement été beaucoup moins de frustration autour de la complexité de ces deux si elles avaient été abstraites. Cela obligerait les développeurs à comprendre comment ils devraient les mettre en place, en le rendant plus évident qu'elles doivent être cohérentes (voir Effective Java). Cependant, je suis plus d'avis qu' hashCode()
, equals()
et clone()
appartiennent distinctes, l'opt-dans des abstractions (c'est à dire des interfaces). Les autres méthodes, wait()
, notify()
, finalize()
, etc. sont suffisamment compliqué et/ou indigènes, il est donc préférable qu'ils sont déjà mises en œuvre, et ne bénéficieront pas d'être prélevée.
Donc je suppose que la réponse serait non, aucune des méthodes de l'Objet serait à l'avantage d'être abstraite.
Serait-il un avantage à la marque de l'Objet de la classe abstraite?
En supposant que tous les moyens sont mis en œuvre, le seul effet de marquage de l'Objet abstrait, c'est qu'il ne peut pas être construite (c - new Object()
est une erreur de compilation). Cela aurait-il un avantage? Je suis de l'avis que le terme "objet" est elle-même abstraite (pouvez-vous trouver quelque chose autour de vous qui peut être complètement décrit comme "un objet"?), donc ça colle bien avec le paradigme orienté objet. Il est cependant, le puriste de côté. Il pourrait être soutenu que le fait de forcer les développeurs à choisir un nom pour tout béton sous-classe, même vides, sera le résultat dans le code qui exprime mieux leur intention. Je pense que, pour être totalement correct en termes de changement de paradigme, les Objets doivent être marqués abstract
, mais quand il descend à lui, il n'y a pas de réel avantage, c'est une question de conception de préférence (le pragmatisme contre la pureté).
C'est la pratique de l'aide d'un Objet ordinaire pour la synchronisation d'une assez bonne raison pour qu'il soit en béton?
De nombreuses autres réponses de parler de la construction d'un objet ordinaire à utiliser dans l' synchronized()
de l'opération. Alors que cela peut avoir été une commune et acceptée pratique, je ne crois pas que ce serait une bonne raison suffisante pour empêcher Objet abstrait si les concepteurs ont voulu qu'il soit. D'autres réponses ont mentionné la façon dont nous devons déclarer un vide, seule sous-classe de l'Objet, de tout temps, nous avons voulu synchroniser sur un certain objet, mais cela ne tient pas debout - vide sous-classe aurait pu être fourni dans le SDK (java.lang.Lock
ou quoi que ce soit), qui pourrait être construit tout temps, nous avons voulu synchroniser. En faisant cela aurait l'avantage de créer une plus forte déclaration d'intention.
Existe-il d'autres facteurs qui pourraient avoir été affectées par les décisions de l'Objet abstrait?
Il y a plusieurs zones distinctes à partir d'un pur point de vue design, ce qui peut avoir influencé le choix. Malheureusement, je ne connais pas assez pour étendre sur eux. Cependant, il ne serait pas surprise me si l'une de ces eu un impact sur la décision:
- Performance
- Sécurité
- La simplicité de mise en œuvre de la JVM
Pourrait-il y avoir d'autres raisons?
Il a été mentionné qu'il peut être en relation à la réflexion. Cependant, la réflexion a été introduite après que l'Objet a été conçu. Donc, si elle affecte la réflexion ou qui n'est pas discutable, c'est pas la raison. De même pour les génériques.
Il y a aussi l'inoubliable point que java.lang.L'objet a été conçu par les humains: ils ont fait une erreur, ils peuvent ne pas avoir considéré la question. Il n'y a pas de langage sans défauts, et ce peut être l'un d'eux, mais si elle l'est, c'est à peine un gros. Et je pense que je peux dire, sans manque d'ambition, que je suis en très peu de chances d'être impliqués dans la conception d'un élément clé d'une telle largement utilisée de la technologie, notamment une qui a duré 15(?) ans et toujours aussi fort, donc il ne devrait pas être considéré comme une critique.
Ayant dit cela, je l'aurais fait à un niveau abstrait ;-p
Résumé
Fondamentalement, aussi loin que je le vois, la réponse à ces deux questions: "Pourquoi est-java.lang.Objet du béton?" ou (si c'était le cas) "Pourquoi est-java.lang.Objet abstrait?"... "Pourquoi pas?".
Plaine les instances de l' java.lang.Object
sont généralement utilisés pour le verrouillage/synchronisation des scénarios et c'est une pratique courante.
Aussi - quelle serait la raison pour qu'il soit abstrait? Parce que c'est pas entièrement fonctionnel dans son propre droit comme un exemple? Pourrait-il vraiment le faire avec certains membres abstraits? Je ne pense pas. Donc l'argument pour le rendre abstrait, en premier lieu, est inexistante. Donc il n'est pas.
Prendre le classique de la hiérarchie des animaux, où vous avez une classe abstraite Animal
, le raisonnement à faire de l' Animal
classe abstraite est parce qu'une instance de l'Animal est effectivement un "invalide" par manque d'un meilleur mot - animal (même si toutes ses méthodes fournissent une base de mise en œuvre). Avec Object
, qui est tout simplement pas le cas. Il n'y a pas de cas écrasante pour le rendre abstrait en premier lieu.
Je peux penser à plusieurs cas où les instances de l' Object
utiles:
- Verrouillage et de synchronisation, comme vous et d'autres intervenants ont mentionné. C'est probablement une odeur de code, mais j'ai vu des instances de l'Objet utilisé de cette façon tout le temps.
- Comme des Objets Nuls, car
equals
renverra toujours false, sauf sur l'instance elle-même. - Dans le code de test, en particulier lors de l'essai de classes de collection. Parfois, il est plus facile de remplir une collection ou un tableau avec des feintes des objets plutôt que d'
null
s. - Comme la base de l'instance pour les classes. Par exemple:
Object o = new Object() {...code here...}
De tout ce que j'ai lu, il semble que l' Object
n'a pas besoin d'être concret, et en fait doit avoir été abstraite.
Non seulement il n'y a pas besoin d'être concret, mais après un peu plus de lecture , je suis convaincu qu' Object
de ne pas être abstrait est en conflit avec la de base modèle d'héritage, il ne faut pas être en permettant à abstraite sous-classes d'une classe concrète, puisque les sous-classes doivent seulement ajouter de la fonctionnalité.
Clairement, ce n'est pas le cas en Java, où nous avons résumé les sous-classes d' Object
.
Je pense qu'il aurait probablement été déclarée abstraite, mais une fois que c'est fait et publié, il est très difficile à défaire sans causer beaucoup de douleur - voir le Langage Java Spec 13.4.1:
"Si une classe qui n'a pas été abstrait est modifié de façon à être déclarée abstraite, puis préexistante binaires qui tentent de créer de nouvelles instances de cette classe seront soit lancer une InstantiationError au moment de la liaison, ou (si une réflexion méthode est utilisée) un InstantiationException au moment de l'exécution; un tel changement n'est donc pas recommandé pour largement distribué des classes."