A déjà été discuté chez CodeRanch. Voir la discussion ici.
missingfaktor
Réponses:
98
Permettez-moi d'abord de mettre en évidence trois façons différentes à des fins similaires.
length- tableaux ( int[], double[], String[]) - de connaître la longueur des tableaux
length()- Chaîne d' objets connexes ( String, StringBuilder, etc.) - de connaître la longueur de la chaîne
size()- Collection d' objets ( ArrayList, Set, etc.) - de connaître la taille de la collection
Maintenant, oubliez de length()considérer juste lengthet size().
lengthn'est pas une méthode, il est donc tout à fait logique qu'elle ne fonctionne pas sur les objets. Cela ne fonctionne que sur les tableaux. size()son nom le décrit mieux et comme c'est une méthode, il sera utilisé dans le cas des objets qui travaillent avec la collection (frameworks de collection) comme je l'ai dit là-haut.
Maintenant, venez à length():
String n'est pas un tableau primitif (donc nous ne pouvons pas utiliser .length) et pas non plus une collection (donc nous ne pouvons pas utiliser .size()) c'est pourquoi nous avons également besoin d'un autre qui est length()(garder les différences et servir le but).
En réponse à Pourquoi?
Je le trouve utile, facile à retenir, à utiliser et convivial.
Un peu simplifié, vous pouvez le considérer comme des tableaux étant un cas particulier et non des classes ordinaires (un peu comme des primitives, mais pas). String et toutes les collections sont des classes, d'où les méthodes pour obtenir la taille, la longueur ou des choses similaires.
Je suppose que la raison au moment de la conception était la performance. S'ils le créaient aujourd'hui, ils avaient probablement proposé quelque chose comme des classes de collection basées sur des tableaux.
Si quelqu'un est intéressé, voici un petit extrait de code pour illustrer la différence entre les deux dans le code généré, d'abord la source:
Couper d'une manière la partie pas si importante du code d'octet, s'exécuter javap -csur la classe entraîne ce qui suit pour les deux dernières lignes:
Dans le premier cas (20-25), le code demande simplement à la JVM la taille du tableau (dans JNI, cela aurait été un appel à GetArrayLength ()) alors que dans le cas String (28-35), il doit faire un appel de méthode pour obtenir la longueur.
Au milieu des années 1990, sans de bons JIT et autres trucs, cela aurait totalement tué les performances de n'avoir que java.util.Vector (ou quelque chose de similaire) et non une construction de langage qui ne se comportait pas vraiment comme une classe mais était rapide. Ils auraient bien sûr pu masquer la propriété comme un appel de méthode et la gérer dans le compilateur mais je pense qu'il aurait été encore plus déroutant d'avoir une méthode sur quelque chose qui n'est pas une vraie classe.
Java traite le tableau comme des objets et les chaînes comme des objets immuables !! : |
Nitish Upreti
@Myth: Je ne vois pas votre point ... La propriété length des tableaux n'est pas un champ public ou quoi que ce soit, c'est une construction du jvm (arraylength est même une opération dans le bytecode). C'est très évident lorsque vous faites JNI ou si vous démontez simplement le code d'où il vient.
Fredrik
Je ne pense pas que le raisonnement de la conception originale était uniquement la performance. Comment implémenteriez-vous Vectorlorsque le langage Java ne prend pas en charge les tableaux?
Holger
8
.lengthest une propriété unique de Java. Il est utilisé pour trouver la taille d'un tableau à une seule dimension .
.length()est une méthode. Il est utilisé pour trouver la longueur d'un fichier String. Cela évite de dupliquer la valeur.
int[] myArray =newint[10];String myString ="hello world!";List<int> myList =newArrayList<int>();
myArray.length // Gives the length of the array
myString.length()// Gives the length of the string
myList.size()// Gives the length of the list
Il est très probable que les chaînes et les tableaux aient été conçus à des moments différents et ont donc fini par utiliser des conventions différentes. Une justification est que puisque les chaînes utilisent des tableaux en interne, une méthode,, a length()été utilisée pour éviter la duplication des mêmes informations. Un autre est que l'utilisation d'une méthode length()permet de souligner l'immuabilité des chaînes, même si la taille d'un tableau est également inchangeable.
En fin de compte, il ne s'agit que d'une incohérence qui a évolué et qui serait définitivement corrigée si le langage était un jour repensé à partir de zéro. Pour autant que je sache, aucun autre langage (C #, Python, Scala, etc.) ne fait la même chose, il s'agit donc probablement d'un léger défaut qui a fini par faire partie du langage.
Vous obtiendrez une erreur si vous utilisez le mauvais de toute façon.
En Java, un tableau stocke sa longueur séparément de la structure qui contient réellement les données. Lorsque vous créez un tableau, vous spécifiez sa longueur et cela devient un attribut déterminant du tableau. Peu importe ce que vous faites à un tableau de longueur N (changer les valeurs, nulles en sortie, etc.), ce sera toujours un tableau de longueur N.
La longueur d'une chaîne est accessoire; ce n'est pas un attribut de la chaîne, mais un sous-produit. Bien que les chaînes Java soient en fait immuables, s'il était possible de changer leur contenu, vous pourriez changer leur longueur. Faire tomber le dernier caractère (si c'était possible) abaisserait la longueur.
Je comprends que c'est une belle distinction, et je vais peut-être être rejetée, mais c'est vrai. Si je crée un tableau de longueur 4, cette longueur de quatre est une caractéristique déterminante du tableau, et est vrai quel que soit ce qu'il contient. Si je crée une chaîne contenant des "chiens", cette chaîne a une longueur de 4 car elle contient quatre caractères.
Je vois cela comme une justification pour faire l'un avec un attribut et l'autre avec une méthode. En vérité, c'est peut-être simplement une incohérence involontaire, mais cela a toujours un sens pour moi, et c'est toujours ainsi que j'y ai pensé.
On m'a appris que pour les tableaux, la longueur n'est pas récupérée via une méthode en raison de la peur suivante: les programmeurs attribueraient simplement la longueur à une variable locale avant d'entrer dans une boucle (pensez à une boucle for où le conditionnel utilise la longueur du tableau.) le ferait soi-disant pour réduire les appels de fonction (et améliorer ainsi les performances). Le problème est que la longueur peut changer pendant la boucle, et la variable ne le ferait pas.
La longueur d'un tableau ne peut pas changer pendant la boucle.
Fredrik
2
vous ne pouvez pas changer la longueur de ce tableau particulier, mais vous pouvez en affecter un nouveau à la même variable
Bozho
2
@Bozho: C'est vrai, mais c'est un autre tableau et si vous faites cela intentionnellement et ne mettez pas à jour ce que vous vérifiez votre boucle, vous avez un bogue. Java n'a jamais eu l'intention de vous empêcher d'écrire des bogues. Vous pouvez faire des boucles infinies, des récursions jusqu'à votre mort et toutes sortes d'erreurs logiques sans que Java n'essaie de vous en empêcher. C'est une bonne raison pour ne pas stocker la longueur dans une variable, mais ce n'est certainement pas la raison pour laquelle elle est conçue de cette façon.
Fredrik
1
Chaque fois qu'un tableau est créé, sa taille est spécifiée. La longueur peut donc être considérée comme un attribut de construction. Pour String, il s'agit essentiellement d'un tableau de caractères. La longueur est une propriété du tableau char. Il n'est pas nécessaire de mettre la longueur comme champ, car tout n'a pas besoin de ce champ.
http://www.programcreek.com/2013/11/start-from-length-length-in-java/
Un objet est une instance de classe ou un tableau .
Le tableau a donc en effet un rôle très spécial en Java. Je me demande pourquoi.
On pourrait dire que le tableau d'implémentation actuel est / était important pour une meilleure performance. Mais c'est une structure interne, qui ne doit pas être exposée.
Ils auraient bien sûr pu masquer la propriété comme un appel de méthode et la gérer dans le compilateur mais je pense qu'il aurait été encore plus déroutant d'avoir une méthode sur quelque chose qui n'est pas une vraie classe.
Je suis d'accord avec Fredrik, qu'une optimisation intelligente du compilateur aurait été le meilleur choix. Cela résoudrait également le problème, que même si vous utilisez une propriété pour les tableaux, vous n'avez pas résolu le problème pour les chaînes et autres types de collections (immuables), car, par exemple, stringest basé sur un chartableau comme vous pouvez le voir sur la définition de classe de String:
En tant qu'ingénieur, je n'aime vraiment pas la réponse "Parce qu'il en a toujours été ainsi". et souhaitait qu'il y ait une meilleure réponse. Mais dans ce cas, il semble que ce soit le cas.
tl; dr
À mon avis, il s'agit d'un défaut de conception de Java et n'aurait pas dû l'implémenter de cette façon.
Réponses:
Permettez-moi d'abord de mettre en évidence trois façons différentes à des fins similaires.
length
- tableaux (int[]
,double[]
,String[]
) - de connaître la longueur des tableauxlength()
- Chaîne d' objets connexes (String
,StringBuilder
, etc.) - de connaître la longueur de la chaînesize()
- Collection d' objets (ArrayList
,Set
, etc.) - de connaître la taille de la collectionMaintenant, oubliez de
length()
considérer justelength
etsize()
.length
n'est pas une méthode, il est donc tout à fait logique qu'elle ne fonctionne pas sur les objets. Cela ne fonctionne que sur les tableaux.size()
son nom le décrit mieux et comme c'est une méthode, il sera utilisé dans le cas des objets qui travaillent avec la collection (frameworks de collection) comme je l'ai dit là-haut.Maintenant, venez à
length()
:String n'est pas un tableau primitif (donc nous ne pouvons pas utiliser
.length
) et pas non plus une collection (donc nous ne pouvons pas utiliser.size()
) c'est pourquoi nous avons également besoin d'un autre qui estlength()
(garder les différences et servir le but).En réponse à Pourquoi?
Je le trouve utile, facile à retenir, à utiliser et convivial.
la source
Un peu simplifié, vous pouvez le considérer comme des tableaux étant un cas particulier et non des classes ordinaires (un peu comme des primitives, mais pas). String et toutes les collections sont des classes, d'où les méthodes pour obtenir la taille, la longueur ou des choses similaires.
Je suppose que la raison au moment de la conception était la performance. S'ils le créaient aujourd'hui, ils avaient probablement proposé quelque chose comme des classes de collection basées sur des tableaux.
Si quelqu'un est intéressé, voici un petit extrait de code pour illustrer la différence entre les deux dans le code généré, d'abord la source:
Couper d'une manière la partie pas si importante du code d'octet, s'exécuter
javap -c
sur la classe entraîne ce qui suit pour les deux dernières lignes:Dans le premier cas (20-25), le code demande simplement à la JVM la taille du tableau (dans JNI, cela aurait été un appel à GetArrayLength ()) alors que dans le cas String (28-35), il doit faire un appel de méthode pour obtenir la longueur.
Au milieu des années 1990, sans de bons JIT et autres trucs, cela aurait totalement tué les performances de n'avoir que java.util.Vector (ou quelque chose de similaire) et non une construction de langage qui ne se comportait pas vraiment comme une classe mais était rapide. Ils auraient bien sûr pu masquer la propriété comme un appel de méthode et la gérer dans le compilateur mais je pense qu'il aurait été encore plus déroutant d'avoir une méthode sur quelque chose qui n'est pas une vraie classe.
la source
Vector
lorsque le langage Java ne prend pas en charge les tableaux?.length
est une propriété unique de Java. Il est utilisé pour trouver la taille d'un tableau à une seule dimension ..length()
est une méthode. Il est utilisé pour trouver la longueur d'un fichierString
. Cela évite de dupliquer la valeur.la source
Considérer:
Il est très probable que les chaînes et les tableaux aient été conçus à des moments différents et ont donc fini par utiliser des conventions différentes. Une justification est que puisque les chaînes utilisent des tableaux en interne, une méthode,, a
length()
été utilisée pour éviter la duplication des mêmes informations. Un autre est que l'utilisation d'une méthodelength()
permet de souligner l'immuabilité des chaînes, même si la taille d'un tableau est également inchangeable.En fin de compte, il ne s'agit que d'une incohérence qui a évolué et qui serait définitivement corrigée si le langage était un jour repensé à partir de zéro. Pour autant que je sache, aucun autre langage (C #, Python, Scala, etc.) ne fait la même chose, il s'agit donc probablement d'un léger défaut qui a fini par faire partie du langage.
Vous obtiendrez une erreur si vous utilisez le mauvais de toute façon.
la source
En Java, un tableau stocke sa longueur séparément de la structure qui contient réellement les données. Lorsque vous créez un tableau, vous spécifiez sa longueur et cela devient un attribut déterminant du tableau. Peu importe ce que vous faites à un tableau de longueur N (changer les valeurs, nulles en sortie, etc.), ce sera toujours un tableau de longueur N.
La longueur d'une chaîne est accessoire; ce n'est pas un attribut de la chaîne, mais un sous-produit. Bien que les chaînes Java soient en fait immuables, s'il était possible de changer leur contenu, vous pourriez changer leur longueur. Faire tomber le dernier caractère (si c'était possible) abaisserait la longueur.
Je comprends que c'est une belle distinction, et je vais peut-être être rejetée, mais c'est vrai. Si je crée un tableau de longueur 4, cette longueur de quatre est une caractéristique déterminante du tableau, et est vrai quel que soit ce qu'il contient. Si je crée une chaîne contenant des "chiens", cette chaîne a une longueur de 4 car elle contient quatre caractères.
Je vois cela comme une justification pour faire l'un avec un attribut et l'autre avec une méthode. En vérité, c'est peut-être simplement une incohérence involontaire, mais cela a toujours un sens pour moi, et c'est toujours ainsi que j'y ai pensé.
la source
On m'a appris que pour les tableaux, la longueur n'est pas récupérée via une méthode en raison de la peur suivante: les programmeurs attribueraient simplement la longueur à une variable locale avant d'entrer dans une boucle (pensez à une boucle for où le conditionnel utilise la longueur du tableau.) le ferait soi-disant pour réduire les appels de fonction (et améliorer ainsi les performances). Le problème est que la longueur peut changer pendant la boucle, et la variable ne le ferait pas.
la source
Chaque fois qu'un tableau est créé, sa taille est spécifiée. La longueur peut donc être considérée comme un attribut de construction. Pour String, il s'agit essentiellement d'un tableau de caractères. La longueur est une propriété du tableau char. Il n'est pas nécessaire de mettre la longueur comme champ, car tout n'a pas besoin de ce champ. http://www.programcreek.com/2013/11/start-from-length-length-in-java/
la source
Je veux juste ajouter quelques remarques à la grande réponse de Fredrik .
La spécification du langage Java dans la section 4.3.1 indique
Le tableau a donc en effet un rôle très spécial en Java. Je me demande pourquoi.
On pourrait dire que le tableau d'implémentation actuel est / était important pour une meilleure performance. Mais c'est une structure interne, qui ne doit pas être exposée.
Je suis d'accord avec Fredrik, qu'une optimisation intelligente du compilateur aurait été le meilleur choix. Cela résoudrait également le problème, que même si vous utilisez une propriété pour les tableaux, vous n'avez pas résolu le problème pour les chaînes et autres types de collections (immuables), car, par exemple,
string
est basé sur unchar
tableau comme vous pouvez le voir sur la définition de classe deString
:Et je ne suis pas d'accord avec le fait que ce serait encore plus déroutant, car array hérite de toutes les méthodes de
java.lang.Object
.En tant qu'ingénieur, je n'aime vraiment pas la réponse "Parce qu'il en a toujours été ainsi". et souhaitait qu'il y ait une meilleure réponse. Mais dans ce cas, il semble que ce soit le cas.
tl; dr
À mon avis, il s'agit d'un défaut de conception de Java et n'aurait pas dû l'implémenter de cette façon.
la source