12

Why was L chosen as the prefix for references in type signatures? Does L stand for something, like B stands for byte, and I stands for int? Or was it chosen because C was already assigned to char?

For example,

System.out.println( new String[0].getClass().getName() );

Yields:

[Ljava.lang.String;

I'm already aware of the explanations in the Java spec and the Class.getName method javadoc.

erickson
  • 265,237
  • 58
  • 395
  • 493
GreenGiant
  • 4,930
  • 1
  • 46
  • 76

3 Answers3

11

This character stem from JVM internal signature and class name representation.

See JVM Specification §4.3.2. Field Descriptors:

  B   byte       signed byte
  C   char       Unicode character code point in the Basic Multilingual Plane,
                 encoded with UTF-16
  D   double     double-precision floating-point value
  F   float      single-precision floating-point value
  I   int        integer
  J   long       long integer
  L ClassName ;  reference             an instance of class ClassName
  S   short      signed short
  Z   boolean    true or false
  [   reference  one array dimension

The array type consist of a [ for each dimension, followed by their element signature, e.g. [I for int[]. Similiarly, Object[] is represented by [Ljava/lang/Object; internally.

It seems, when the conversion from internal class name to application visible name, i.e. returned by Class.getName() was first implemented, it was implemented as just converting / to . but without care for the array notation. Later on, it wasn’t changed for compatibility reasons.


Note the Java 8 introduced getTypeName() to solve the issue, i.e. String[].class.getTypeName() yields java.lang.String[].

Holger
  • 285,553
  • 42
  • 434
  • 765
  • 4
    Yes. But why `L` specifically, instead of some other letter? Was it arbitrary? Or did it have some meaning? – GreenGiant Sep 24 '15 at 18:30
  • 2
    I don’t know the reason (yet) but there must be one. It’s apparent, that the letters for primitive types are simply derived from their names, except for the one which clashes, i.e. `Z` for `boolean` because `B` is already used for `byte`. And there, `long` had to go with `J` because `L` is already reserved for reference types. I guess, you wouldn’t create a name clash, if you just can pick *any* character, so there must be a reason for choosing `L` for reference types. – Holger Sep 24 '15 at 18:41
  • `long` comes after reference type? – ZhongYu Sep 24 '15 at 19:01
  • 1
    @bayou.io: by which ordering? – Holger Sep 24 '15 at 19:05
  • 1
    why was 'L' reserved for reference, but not `long`, which seems more natural. unless, `long` type was introduced later? – ZhongYu Sep 24 '15 at 19:06
  • 7
    Well, I grabbed an “Oak Language Specification 0.2” and it already contains `long` (amongst unsigned types). And even if there was a time without `long` type, I guess by the time, the unsigned types were removed (when it became Java), there was a chance of reassigning the characters. Maybe it means, type requiring **L**inkage, or so… – Holger Sep 24 '15 at 19:14
0

The "[" is the dimension of the array. So "[" is a 1-dimensional array, "[[" is a 2 -dimensional array, etc.

The "Ljava.lang.String" indicates that it is an array of objects (that's the "L") of class java.lang.String.

If you had an array of primitives, say, int, it would be "[I". Other primitive types have different letters.

Matthew McPeak
  • 17,705
  • 2
  • 27
  • 59
-3

[Ljava.lang.String;

Here [ means an array. L means a class of type java.lang.String. These are the shortcuts JVM keeps for itself for identifying Java data types. That's similar to the type descriptors used internally in the bytecode. For instance, for primitives the value is: [I for array of int, a two-dimensional array would be: [[I.

Here is a very good explanation: [L array notation - where does it come from?

Community
  • 1
  • 1
rakesh
  • 602
  • 1
  • 5
  • 23