89 votes

[Notation L tableau - d'où vient-il?

J'ai souvent vu des messages qui utilisent [L puis un type pour désigner un tableau, par exemple:

[Ljava.lang.Object; cannot be cast to [Ljava.lang.String;

(L'exemple ci-dessus étant un exemple arbitraire que je viens de citer.) Je sais que cela signifie un tableau, mais d'où vient la syntaxe? Pourquoi le début [ mais pas de crochet final? Et pourquoi le L? Est-ce purement arbitraire ou existe-t-il une autre raison historique / technique?

87voto

OscarRyz Points 82553

[ est synonyme de Tableau, l' Lsome.type.Here signifie que le type. C'est similaire au type de descripteurs utilisés en interne dans le bytecode vu en §4.3 de la Machine Virtuelle Java Spécification -- choisis pour être aussi bref que possible. La seule différence est que le réel descripteurs d'utilisation / plutôt que d' . pour la dénotation de paquets.

Par exemple, pour les primitives de la valeur est: [I pour le tableau de int, un tableau à deux dimensions seraient: [[I.

Étant donné que les classes peuvent avoir n'importe quel nom, il serait plus difficile de déterminer dans quelle classe il est, d'où l' L, le nom de la classe se termine avec un ;

Les descripteurs sont également utilisés pour représenter les types de champs et de méthodes.

Par exemple:

(IDLjava/lang/Thread;)Ljava/lang/Object;

... correspond à une méthode dont les paramètres sont int, double, et Thread et le type de retour est - Object

modifier

Vous pouvez également voir ce dans le .les fichiers de classe en utilisant le java dissambler

C:>more > S.java
class S {
  Object  hello(int i, double d, long j, Thread t ) {
   return new Object();
  }
}
^C
C:>javac S.java

C:>javap -verbose S
class S extends java.lang.Object
  SourceFile: "S.java"
  minor version: 0
  major version: 50
  Constant pool:
const #1 = Method       #2.#12; //  java/lang/Object."<init>":()V
const #2 = class        #13;    //  java/lang/Object
const #3 = class        #14;    //  S
const #4 = Asciz        <init>;
const #5 = Asciz        ()V;
const #6 = Asciz        Code;
const #7 = Asciz        LineNumberTable;
const #8 = Asciz        hello;
const #9 = Asciz        (IDJLjava/lang/Thread;)Ljava/lang/Object;;
const #10 = Asciz       SourceFile;
const #11 = Asciz       S.java;
const #12 = NameAndType #4:#5;//  "<init>":()V
const #13 = Asciz       java/lang/Object;
const #14 = Asciz       S;

{
S();
  Code:
   Stack=1, Locals=1, Args_size=1
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return
  LineNumberTable:
   line 1: 0


java.lang.Object hello(int, double, long, java.lang.Thread);
  Code:
   Stack=2, Locals=7, Args_size=5
   0:   new     #2; //class java/lang/Object
   3:   dup
   4:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   7:   areturn
  LineNumberTable:
   line 3: 0


}

Et en raw fichier de classe ( regardez à la ligne 5 ):

enter image description here

Référence: Champ description sur la spécification de la JVM

59voto

Descripteurs de tableau JVM.

 [Z = boolean
[B = byte
[S = short
[I = int
[J = long
[F = float
[D = double
[C = char
[L = any non-primitives(Object)
 

Pour obtenir le type de données principal, vous avez besoin de:

 [Object].getClass().getComponentType();
 

Il retournera null si "l'objet" n'est pas un tableau. pour déterminer s'il s'agit d'un tableau, appelez simplement:

 [Any Object].getClass().isArray()
 

ou

 Class.class.isArray();
 

12voto

EboMike Points 39257

Il est utilisé dans la JNI (et la JVM en interne en général) pour indiquer un type. Les Primitives sont représentées par une seule lettre (Z booléenne, j'ai int, etc), [ indique un tableau, et L est utilisé pour une classe (terminée par un ;).

Voir ici: JNI Types

EDIT: Pour expliquer pourquoi il n'est pas appelé à disparaître ] - ce code est de permettre à la JNI/JVM pour repérer rapidement une méthode et de sa signature. Il est destiné à être le plus compact possible pour rendre l'analyse rapide (=que peu de caractères que possible), alors [ est utilisé pour un tableau qui est assez simple (quel meilleur symbole pour l'utiliser?). I pour int est tout aussi évident.

9voto

Stephen C Points 255558

[L notation de tableau - d'où vient-elle?

À partir de la JVM spec. C'est la représentation des noms de type qui est spécifié dans le classFile format et d'autres endroits.

  • Le " ["désigne un tableau. En fait, la matrice type de nom est - [<typename><typename> est le nom du type de base de la matrice.
  • "L" est en fait partie de la base de type nom; par exemple, la Chaîne est - "Ljava.lang.String;". Note de fin ';'!!

Et oui, la notation est documenté dans d'autres endroits aussi bien.

Pourquoi?

Il ne fait aucun doute que ce type interne d'une représentation de nom a été choisi parce qu'il est:

  • compact,
  • auto-délimitation (ce qui est important pour les représentations de signatures de méthode, et c'est pourquoi le 'L' et le second ';' sont là), et
  • utilise les caractères imprimables (pour la lisibilité ... si ce n'est des raisons de lisibilité).

Mais c'est pas clair pourquoi ils ont décidé d'exposer le type interne noms de types de tableau via l' Class.getName() méthode. Je pense qu'ils pourraient avoir cartographié les noms internes à quelque chose de plus "conviviale". Ma meilleure supposition est que c'était juste une de ces choses qu'ils n'ont pas l'obtenir autour de la fixation jusqu'à ce qu'il soit trop tard. (Personne n'est parfait ... même pas l'hypothétique "concepteur intelligent".)

3voto

Paŭlo Ebermann Points 35526

Une autre source pour cela serait la documentation de Class.getName () . Bien sûr, toutes ces spécifications sont congruentes, car elles sont conçues pour s’adapter.

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