[L 배열 표기법-어디에서 왔습니까?
[L
예를 들어 배열을 나타내는 데 유형을 사용하는 메시지를 자주 보았습니다 .
[Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
(위는 방금 뽑은 임의의 예입니다.) 이것이 배열을 의미한다는 것을 알고 있지만 구문은 어디에서 왔습니까? 왜 시작 [
이지만 닫는 대괄호는 없습니까? 그리고 왜 L? 순전히 임의적입니까 아니면 그 뒤에 다른 역사적 / 기술적 이유가 있습니까?
[
Lsome.type.Here
유형을 의미하는 배열을 의미합니다. 이는 Java Virtual Machine Specification의 §4.3 에서 볼 수 있는 바이트 코드에서 내부적으로 사용되는 유형 설명자 ( 가능한 한 간략하게 선택) 와 유사 합니다 . 유일한 차이점은 실제 설명자가 패키지를 표시 하는 대신 사용 한다는 것 입니다./
.
예를 들어 프리미티브의 경우 값은 다음과 같습니다. [I
int 배열의 경우 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 행 참조) :
참조 : 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
'Nice programing' 카테고리의 다른 글
WiX 제거시 파일 제거 (0) | 2020.10.16 |
---|---|
LINQ to SQL의 TransactionScope와 Transaction (0) | 2020.10.16 |
Django에서 manage.py를 사용하여 CLI에서 데이터베이스를 지우는 가장 쉬운 방법은 무엇입니까? (0) | 2020.10.16 |
Java 7은 방화벽이 켜져있는 경우 Windows Vista 및 7에서 FTP 전송을 차단합니다. (0) | 2020.10.16 |
Facebook 로그인에 대해 앱이 잘못 구성됨 : Android Facebook 통합 문제 (0) | 2020.10.16 |