longueur et longueur () en Java


Pourquoi avons-nous la longueur d'un tableau comme un attribut, array.length, et pour la Chaîne, nous avons une méthode, str.length()?

Y a-t-il une raison?

Author: Peter Mortensen, 2009-12-27

8 answers

Permettez-moi d'abord de souligner trois façons différentes à des fins similaires.

length -- les tableaux (int[], double[], String[]) -- pour connaître la longueur des tableaux

length() -- Objet lié à une chaîne (String, StringBuilder, etc) to pour connaître la longueur de la chaîne

size() -- Objet de Collection (ArrayList, Set, etc) - à savoir la taille de la Collection

Maintenant oublier length() considérer length et size().

length n'est pas une méthode, de sorte complètement de sens qu'il ne va pas travailler sur des 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 (cadres de collection) comme je l'ai dit là-haut.

Maintenant, venez à length():
String n'est pas un tableau primitif (nous ne pouvons donc pas utiliser .length) et pas non plus une Collection (nous ne pouvons donc pas utiliser .size()) c'est pourquoi nous avons également besoin d'un tableau différent qui est length() (gardez les différences et de servir le but).

Comme réponse à Pourquoi?
Je le trouve utile, facile à retenir et à utiliser et convivial.

 89
Author: Saif, 2017-02-07 10:13:46

Un peu simplifié, vous pouvez le considérer comme des tableaux étant 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 avaient probablement trouvé quelque chose comme des classes de collection soutenues par un tableau à la place.

Si quelqu'un est intéressé, voici un petit extrait de code pour illustrez la différence entre les deux dans le code généré, d'abord la 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());
  }
}

Couper d'une manière la partie pas si importante du code octet, en exécutant javap -c sur la classe entraîne 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 la taille du tableau (dans JNI, cela aurait été un appel à GetArrayLength()) alors que dans le cas de la chaîne (28-35), il doit faire un appel de méthode pour obtenir la longueur.

Au milieu des années 1990, sans de bons JITs et d'autres choses, il aurait totalement tué les performances de n'avoir que le java.util.Vector (ou quelque chose de similaire) et pas 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 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.

 25
Author: Fredrik, 2018-02-08 18:29:45

.length est une propriété de Java. Il est utilisé pour trouver la taille d'un tableau unidimensionnel .

.length() est une méthode. Il est utilisé pour trouver la longueur d'un String. Cela évite de dupliquer la valeur.

 7
Author: Prabandha, 2017-04-10 08:01:18

Considérons:

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 ont é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, length(), a été utilisée pour éviter la duplication des mêmes informations. Une autre est que l'utilisation d'une méthode length() permet de souligner l'immutabilité de chaînes, même si la taille d'un tableau est aussi immuable.

En fin de compte, ce n'est qu'une incohérence qui a évolué serait certainement fixé si la langue était jamais repensée à partir de zéro. Pour autant que je sache, aucun autre langage (C#, Python, Scala, etc.) faire la même chose, donc c'est probablement juste un léger défaut qui a fini en partie de la langue.

Vous obtiendrez une erreur si vous utilisez le mauvais de toute façon.

 7
Author: Gordon Gustafson, 2018-02-07 21:33:45

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 de définition du Tableau. Peu importe ce que vous faites à un tableau de longueur N (changer les valeurs, les choses nulles, 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 changez leur contenu, vous pouvez changer leur longueur. Supprimer le dernier caractère (si c'était possible) réduirait la longueur.

Je comprends que c'est une belle distinction, et je peux être rejeté pour cela, mais c'est vrai. Si je fais 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 tenu à l'intérieur. Si je fais une chaîne qui contient des "chiens", cette chaîne est de longueur 4 car elle contient quatre caractères.

Je voir cela comme une justification pour faire un avec un attribut et l'autre avec une méthode. En vérité, c'est peut-être une incohérence involontaire, mais cela a toujours eu du sens pour moi, et c'est toujours comme ça que j'y ai pensé.

 2
Author: jakeboxer, 2009-12-27 08:39:43

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 crainte suivante: les programmeurs assigneraient 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 programmeur le ferait soi-disant pour réduire les appels de fonction (et ainsi améliorer les performances.) Le problème est que la longueur peut changer pendant la boucle, et la variable ne le ferait pas.

 1
Author: Matthew, 2009-12-27 08:39:54

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. Length est une propriété du tableau char. Il n'est pas nécessaire de mettre length en tant que champ, car tout n'a pas besoin de ce champ. http://www.programcreek.com/2013/11/start-from-length-length-in-java/

 0
Author: Ryan, 2013-11-25 16:38:19

Je veux juste ajouter quelques remarques à la grande réponse par , Fredrik.

La spécification du langage Java dans la section 4.3.1 indique

Un objet est une instance de classe ou un tableau .

Donc array a en effet un rôle très spécial en Java. Je me demande pourquoi.

On pourrait soutenir que le tableau d'implémentation actuel est/était important pour une meilleure performance. Mais que c'est une structure interne, qui ne devrait pas être exposé.

Ils auraient bien sûr pu masquer la propriété en tant qu'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 collection (immuables), car, par exemple, string est basé sur un tableau char comme vous pouvez le voir sur la définition de classe de String:

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {           
    private final char value[]; // ...

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 que ça a toujours été comme ça."et a souhaité qu'il y ait une meilleure réponse. Mais dans ce cas il semble être.

Tl;dr

Dans mon opinion, c'est un défaut de conception de Java et n'aurait pas dû être implémenté de cette façon.

 -1
Author: Michael Dorner, 2017-11-03 15:01:30