Pourquoi avons-nous la longueur d'un tableau en tant qu'attribut, array.length
, et pour String, nous avons une méthode, str.length()
?
Y a-t-il une raison?
Permettez-moi d'abord de souligner trois manières différentes d'atteindre un objectif similaire.
length
- tableaux (int[]
, double[]
, String[]
) - pour connaître la longueur des tableaux
length()
- Objet lié à une chaîne (String
, StringBuilder
, etc.) - pour connaître la longueur de la chaîne
size()
- Objet de collection (ArrayList
, Set
, etc.) - pour connaître la taille de la collection
Maintenant, oubliez length()
, considérez seulement length
et size()
.
length
n'est pas une méthode, il est donc parfaitement logique que cela ne fonctionne pas sur les objets. Cela ne fonctionne que sur les tableaux.size()
son nom la décrit mieux et comme il s’agit d’une méthode, elle sera utilisée dans le cas des objets qui travaillent avec collection (framework de collection), comme je l’ai dit plus haut.
Maintenant, venez danslength()
:
String n'est pas un tableau primitif (nous ne pouvons donc pas utiliser .length
) ni une collection (nous ne pouvons donc pas utiliser .size()
). C'est pourquoi nous avons également besoin d'un autre, qui est length()
(conservez les différences et remplissez le rôle voulu) .
En réponse à Pourquoi?
Je le trouve utile, facile à mémoriser et à utiliser et convivial.
Un peu simplifié, vous pouvez penser que les tableaux constituent un cas spécial 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 l'ont créé aujourd'hui, ils auraient probablement créé quelque chose comme des classes de collection reposant sur un tableau.
Si quelqu'un est intéressé, voici un petit extrait de code illustrant la différence entre les deux codes générés, tout d'abord le code source:
public class LengthTest {
public static void main(String[] args) {
int[] array = {12,1,4};
String string = "Hoo";
System.out.println(array.length);
System.out.println(string.length());
}
}
En coupant la partie la moins importante du code octet, exécuter javap -c
sur la classe a pour résultat ce qui suit pour les deux dernières lignes:
20: getstatic #3; //Field Java/lang/System.out:Ljava/io/PrintStream;
23: aload_1
24: arraylength
25: invokevirtual #4; //Method Java/io/PrintStream.println:(I)V
28: getstatic #3; //Field Java/lang/System.out:Ljava/io/PrintStream;
31: aload_2
32: invokevirtual #5; //Method Java/lang/String.length:()I
35: invokevirtual #4; //Method Java/io/PrintStream.println:(I)V
Dans le premier cas (20-25), le code demande simplement à la JVM de préciser la taille du tableau (dans JNI, cela aurait été un appel à GetArrayLength ()), alors que dans le cas String (28-35), appel de méthode pour obtenir la longueur.
Au milieu des années 90, sans de bons JIT et autres choses, il aurait été totalement inefficace d'avoir uniquement 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é en tant qu'appel de méthode et la manipuler dans le compilateur, mais je pense que cela aurait été encore plus déroutant d'avoir une méthode sur quelque chose qui n'est pas une vraie classe.
Considérer:
int[] myArray = new int[10];
String myString = "hello world!";
List<int> myList = new ArrayList<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 différentes conventions. Une justification est que, puisque les chaînes utilisent des tableaux en interne, une méthode, length()
, a été utilisée pour éviter la duplication des mêmes informations. Une autre est que l'utilisation de la méthode length()
permet de souligner l'immuabilité des chaînes, même si la taille d'un tableau est également non modifiable.
En fin de compte, il s’agit simplement d’une incohérence qui a évolué et qui serait définitivement corrigée si le langage était repensé de fond en comble. 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 quand même une erreur si vous utilisez le mauvais.
.length
est une propriété unique de Java. Il est utilisé pour trouver la taille d'une seule dimension array .
.length()
est une méthode. Il est utilisé pour trouver la longueur d'unString
. Cela évite de dupliquer la valeur.
En Java, un tableau stocke sa longueur séparément de la structure qui contient les données. Lorsque vous créez un tableau, vous spécifiez sa longueur et cela devient un attribut de définition du tableau. Quoi que vous fassiez avec un tableau de longueur N (changement de valeur, valeur nulle, 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 de caractères Java soient en réalité immuables, il est possible de changer leur longueur s’il était possible de changer leur contenu. Faire tomber le dernier caractère (si c'était possible) réduirait la longueur.
Je comprends que la distinction est bonne et que je risque d’ê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 vraie indépendamment de ce qui est contenu à l'intérieur. 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é, il s’agit peut-être d’une incohérence non intentionnelle, mais j’ai toujours eu 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 par une méthode en raison de la crainte suivante: les programmeurs attribueraient simplement la longueur à une variable locale avant d'entrer dans une boucle (imaginez une boucle for où le conditionnel utilise la longueur du tableau.) serait supposé le faire 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 que la variable ne le ferait pas.
Chaque fois qu'un tableau est créé, sa taille est spécifiée. Donc, la longueur peut ê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 de caractères. Il n'est pas nécessaire de mettre la longueur en champ, car tout n'a pas besoin de ce champ . http://www.programcreek.com/2013/11/start-from-length-length-in-Java/