Nice programing

[L 배열 표기법-어디에서 왔습니까?

nicepro 2020. 10. 16. 08:04
반응형

[L 배열 표기법-어디에서 왔습니까?


[L예를 들어 배열을 나타내는 데 유형을 사용하는 메시지를 자주 보았습니다 .

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

(위는 방금 뽑은 임의의 예입니다.) 이것이 배열을 의미한다는 것을 알고 있지만 구문은 어디에서 왔습니까? 왜 시작 [이지만 닫는 대괄호는 없습니까? 그리고 왜 L? 순전히 임의적입니까 아니면 그 뒤에 다른 역사적 / 기술적 이유가 있습니까?


[Lsome.type.Here유형을 의미하는 배열을 의미합니다. 이는 Java Virtual Machine Specification의 §4.3 에서 볼 수 있는 바이트 코드에서 내부적으로 사용되는 유형 설명자 ( 가능한 한 간략하게 선택) 와 유사 합니다 . 유일한 차이점은 실제 설명자가 패키지를 표시 하는 대신 사용 한다는 것 입니다./.

예를 들어 프리미티브의 경우 값은 다음과 같습니다. [Iint 배열의 경우 2 차원 배열은 다음과 같습니다 [[I..

클래스는 어떤 이름을 가질 수 있으므로 어떤 클래스인지 식별하기가 더 어렵습니다. 따라서 L클래스 이름은로 끝납니다.;

설명자는 필드 및 메서드 유형을 나타내는데도 사용됩니다.

예를 들면 :

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

... 매개 변수가 int, double이고 Thread반환 유형이 다음과 같은 메서드에 해당합니다.Object

편집하다

java dissambler를 사용하여 .class 파일에서도 이것을 볼 수 있습니다.

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


}

그리고 원시 클래스 파일 (5 행 참조) :

enter image description here

참조 : JVM 사양에 대한 필드 설명


JVM 배열 설명자.

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

기본 데이터 유형을 얻으려면 다음이 필요합니다.

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

"객체"가 배열이 아닌 경우 null을 반환합니다. 배열인지 확인하려면 다음을 호출하십시오.

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

또는

Class.class.isArray();

이것은 유형을 표시하기 위해 JNI (및 일반적으로 JVM 내부적으로)에서 사용됩니다. 프리미티브는 단일 문자 (부울의 경우 Z, 정수의 경우 I 등)로 [표시되고 배열을 나타내며 L은 클래스 (a로 끝남 ;)에 사용됩니다.

여기 참조 : JNI 유형

EDIT: To elaborate on why there is no terminating ] - this code is to allow the JNI/JVM to quickly identify a method and its signature. It's intended to be as compact as possible to make parsing fast (=as few characters as possible), so [ is used for an array which is pretty straightforward (what better symbol to use?). I for int is equally obvious.


[L array notation - where does it come from?

From the JVM spec. This is the representation of type names that is specified in the classFile format and other places.

  • The '[' denotes an array. In fact, the array type name is [<typename> where <typename> is the name of the base type of the array.
  • 'L' is actually part of the base type name; e.g. String is "Ljava.lang.String;". Note the trailing ';'!!

And yes, the notation is documented in other places as well.

Why?

There is no doubt that that internal type name representation was chosen because it is:

  • compact,
  • self-delimiting (this is important for representations of method signatures, and it's why the 'L' and the trailing ';' are there), and
  • uses printable characters (for legibility ... if not readability).

But it is unclear why they decided to expose the internal type names of array types via the Class.getName() method. I think they could have mapped the internal names to something more "human friendly". My best guess is that it was just one of those things that they didn't get around to fixing until it was too late. (Nobody is perfect ... not even the hypothetical "intelligent designer".)


I think it's because C was taken by char, so next letter in class is L.


Another source for this would be the documentation of Class.getName(). Of course, all these specifications are congruent, since they are made to fit each other.

참고URL : https://stackoverflow.com/questions/5085889/l-array-notation-where-does-it-come-from

반응형