발기부전이란 무엇이며 어떻게 사용하는가?
JVM에 추가되는 모든 신기능에 대해 계속 듣고 있는데, 그 중 하나의 기능이 호출되고 있습니다.자바에서 리플렉티브 프로그래밍을 어떻게 더 쉽게 또는 더 좋게 할 수 있는지 알고 싶습니다.
이것은 컴파일러가 이전에 가능했던 것보다 느슨한 사양의 메서드를 호출하는 코드를 생성할 수 있도록 하는 새로운 JVM 명령입니다.duck typing이 무엇인지 알고 있다면 기본적으로 revokedynamic은 duck typing을 허용합니다.Java 프로그래머로서 할 수 있는 일은 많지 않습니다.단, 툴 크리에이터라면 이 툴을 사용하여 보다 유연하고 효율적인 JVM 기반의 언어를 구축할 수 있습니다.여기 많은 세부사항을 알려주는 정말 달콤한 블로그 게시물이 있습니다.
Java Records 기사의 일부로서 Invoke Dynamic의 배후에 있는 동기에 대해 설명했습니다.먼저 인디에 대한 대략적인 정의부터 시작합시다.
인디 ★★★
Invoke Dynamic(Indy라고도 함)은 JSR 292의 일부로 다이내믹 타입 언어에 대한 JVM 지원을 강화하기 위한 것입니다.Java 7에서의 첫 출시 후,invokedynamic
와 그 opcode의 opcode.java.lang.invoke
짐은 JRuby와 같은 동적 JVM 기반 언어에 의해 상당히 광범위하게 사용됩니다.
동적 언어 지원을 강화하도록 특별히 설계되었지만, 그 이상의 기능을 제공합니다.사실, 언어 디자이너가 역동적인 타입의 곡예에서 역동적인 전략까지 어떤 형태의 역동성이든 필요로 하는 곳에 사용하기에 적합합니다!
예를 들어 Java 8 Lambda Expressions는 실제로 다음과 같이 구현됩니다.invokedynamic
자바가 정적으로 입력된 언어임에도 불구하고!
사용자 정의 바이트 코드
은 네 메서드 유형을 했습니다. 즉, JVM은 네 가지 메서드 호출 유형을 지원했습니다.invokestatic
메서드를 하려면 , 「」를 참조해 주세요.invokeinterface
메서드를 하려면 , 「 메서드」를 사용합니다.invokespecial
super()
및 " " " or or or or"invokevirtual
이치노
차이에도 불구하고, 이러한 호출 유형은 하나의 공통 특성을 공유합니다. 즉, 우리는 우리의 논리로 그것들을 풍부하게 할 수 없습니다.반대로,invokedynamic
를 사용하면 호출 프로세스를 원하는 방식으로 부트스트랩할 수 있습니다.【JVM】부츠스트레이프.
Indy ind ind ind ind
이 JVM을 때invokedynamic
이 명령어는 부트스트랩 메서드라고 불리는 특별한 정적 메서드를 호출합니다.부트스트랩 메서드는 실제 부팅되는 로직을 준비하기 위해 작성한 Java 코드입니다.
다음 는 "하다"의 합니다.java.lang.invoke.CallSite
이거.CallSite
실제 방법에 대한 참조가 있습니다.MethodHandle
.
이 이 을 볼 invokedynamic
이 명령에서는 저속 경로를 건너뛰고 기본 실행 파일을 직접 호출합니다.JVM은 변화가 없는 한 느린 경로를 계속 건너뜁니다.
: : Java 14 레드
14 바 1414Records
는 덤 .
이 간단한 기록을 고려하면:
public record Range(int min, int max) {}
이 예의 바이트 코드는 다음과 같습니다.
Compiled from "Range.java"
public java.lang.String toString();
descriptor: ()Ljava/lang/String;
flags: (0x0001) ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokedynamic #18, 0 // InvokeDynamic #0:toString:(LRange;)Ljava/lang/String;
6: areturn
부트스트랩 방식 테이블에서 다음을 수행합니다.
BootstrapMethods:
0: #41 REF_invokeStatic java/lang/runtime/ObjectMethods.bootstrap:
(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;
Ljava/lang/invoke/TypeDescriptor;Ljava/lang/Class;
Ljava/lang/String;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;
Method arguments:
#8 Range
#48 min;max
#50 REF_getField Range.min:I
#51 REF_getField Range.max:I
따라서 Records의 부트스트랩 메서드는bootstrap
에 있습니다.java.lang.runtime.ObjectMethods
보시다시피 이 부트스트랩 방식에서는 다음 파라미터가 필요합니다.
- 의
MethodHandles.Lookup
(</FONT CHANGE:>).Ljava/lang/invoke/MethodHandles$Lookup
을 사용하다 - 서드즉즉( ),
toString
,equals
,hashCode
를 들어, 값이 「」인 경우, 「」toString
「」, 「」를 합니다.ConstantCallSite
)CallSite
것)을 가리키고 .toString
이 특정 기록에 대한 구현. TypeDescriptor
에서는 (이 방법에서는)Ljava/lang/invoke/TypeDescriptor
을 사용하다- 토큰: " " " )
Class<?>
레코드 클래스 타입을 나타냅니다.★★★★★★★★★★★★★★★입니다Class<Range>
★★★★★★★★★★★★★★★★★★, - 이름을 「」).
min;max
. - , 하나.
MethodHandle
하면 에서 " "가 됩니다.MethodHandle
이 특정 메서드 구현의 컴포넌트를 기반으로 합니다.
invokedynamic
명령어는 이러한 인수를 모두 부트스트랩 메서드에 전달합니다."Bootstrap"이라는가 반환됩니다.ConstantCallSite
이거.ConstantCallSite
는 요청된 메서드 구현에 대한 참조를 보유하고 있습니다.toString
.
왜왜??
Reflection API는 ★★★java.lang.invoke
JVM은 모든 호출을 완벽하게 파악할 수 있기 때문에 API는 매우 효율적입니다.따라서 JVM은 가능한 한 느린 경로를 피하면 모든 종류의 최적화를 적용할 수 있습니다.
인수와 「」는invokedynamic
접근법이 단순하기 때문에 신뢰성이 높고 덜 취약합니다.
또한 Java Records용으로 생성된 바이트 코드는 속성 수와 독립적입니다.따라서 바이트 코드가 줄어들고 부팅 시간이 단축됩니다.
마지막으로 Java의 새로운 버전에 새롭고 효율적인 부트스트랩 방식의 구현이 포함되어 있다고 가정해 보겠습니다.★★★★★★★★★★★★★★★★ invokedynamic
재컴파일 없이 이 개선점을 활용할 수 있습니다.이렇게 하면 포워드 바이너리 호환성을 얻을 수 있습니다.그리고 이것이 바로 우리가 얘기했던 역동적인 전략입니다!
기타 예
Java Records와 더불어 invoke dynamic은 다음과 같은 기능을 구현하기 위해 사용되고 있습니다.
- Java 8+에서의 람다 식:
- Java 9+에서의 문자열 연결:
얼마 전 C#에서 C#에 쿨한 기능, 다이내믹 구문을 추가했습니다.
Object obj = ...; // no static type available
dynamic duck = obj;
duck.quack(); // or any method. no compiler checking.
반사 메서드 호출에 대한 구문설탕이라고 생각하시면 됩니다.그것은 매우 흥미로운 응용 프로그램을 가질 수 있다.http://www.infoq.com/presentations/Statically-Dynamic-Typing-Neal-Gafter 를 참조해 주세요.
C#의 다이내믹한 타입을 담당하고 있는 Neal Gafter는 SUN에서 MS로 망명한 지 얼마 되지 않았기 때문에 SUN 내부에서도 같은 일이 논의되었다고 해도 무리는 아니다.
그 후 얼마 지나지 않아 어떤 자바 친구가 비슷한 걸 발표했는데
InvokeDynamic duck = obj;
duck.quack();
유감스럽게도 Java 7에서는 이 기능을 찾을 수 없습니다.우우실실실실다다, 그들은 할 수 있는 .invokedynamic
로그프
발기된 유행을 계속하기 전에 이해해야 할 두 가지 개념이 있습니다.
1. 정적과동적 입력
정적 - 컴파일 시 사전 양식 유형 검사(예: Java)
동적 - 실행 시 사전 양식 유형 검사(예: JavaScript)
Type Check는 프로그램이 type safe인지 확인하는 프로세스입니다.즉, 클래스 및 인스턴스 변수, 메서드 매개 변수, 반환 값 및 기타 변수의 입력 정보를 확인합니다.예: Java는 int, String 등에 대해 알고 있습니다.컴파일 시에 JavaScript 내의 오브젝트 타입은 실행 시에만 판별할 수 있습니다.
2. 강한 vs.서투른 타이핑이 약하다
강력 - 작업에 제공되는 값 유형에 대한 제한(예: Java)을 지정합니다.
취약 - 작업에 호환되지 않는 유형(예: Visual Basic)이 있는 경우 해당 인수를 변환(캐스트)합니다.
Java가 정적이고 약하게 입력된 언어라는 것을 알고 JVM에 동적 및 강하게 입력된 언어를 구현하려면 어떻게 해야 합니까?
호출된 시스템은 프로그램 컴파일 후 메서드 또는 함수의 가장 적절한 구현을 선택할 수 있는 런타임 시스템을 구현합니다.
예:(a + b)가 있고 컴파일 시 변수 a, b에 대해 아무것도 모르면 호출된ynamic은 런타임에 이 작업을 Java에서 가장 적절한 메서드에 매핑합니다.예를 들어 a, b가 Strings로 판명된 경우 메서드(String a, String b)를 호출합니다.a, b가 ints인 경우 메서드(int a, int b)를 호출합니다.
revokedynamic은 Java 7에서 도입되었습니다.
언급URL : https://stackoverflow.com/questions/6638735/whats-invokedynamic-and-how-do-i-use-it
'programing' 카테고리의 다른 글
Ag 그리드에서 열을 숨기는 방법 (0) | 2022.08.19 |
---|---|
1 ~ 10의 Java 난수 생성 (0) | 2022.08.19 |
vue.js의 어레이에 항목이 이미 있는지 확인하는 방법 (0) | 2022.08.14 |
0과 1 사이의 랜덤 부동 생성 (0) | 2022.08.14 |
라우터 뷰에서 외부 컴포넌트로의 Vuej (0) | 2022.08.14 |