programing

발기부전이란 무엇이며 어떻게 사용하는가?

yoursource 2022. 8. 14. 14:58
반응형

발기부전이란 무엇이며 어떻게 사용하는가?

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메서드를 하려면 , 「 메서드」를 사용합니다.invokespecialsuper() 및 " " " 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.invokeJVM은 모든 호출을 완벽하게 파악할 수 있기 때문에 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

반응형