소스 코드를 Java 바이트 코드로 변환하는 용도는 무엇입니까?


37

다른 아키텍처에 대해 다른 JVM이 필요한 경우이 개념을 도입 한 논리가 무엇인지 알 수 없습니다. 다른 언어에서는 기계마다 다른 컴파일러가 필요하지만 Java에서는 다른 JVM이 필요하므로 JVM 개념 또는 추가 단계를 도입하는 데 필요한 논리는 무엇입니까 ??



12
@ gnat : 사실, 그것은 중복이 아닙니다. 이것은 "소스 vs 바이트 코드", 즉 첫 번째 변환입니다. 언어 측면에서 이것은 Javascript와 Java입니다. 귀하의 링크는 C ++ 대 Java입니다.
MSalters

2
업그레이드를 위해 디지털 코딩을 추가하는 50 개의 어플라이언스 모델 또는 50 개의 다른 하드웨어에 대해 50 개의 컴파일러를위한 간단한 바이트 코드 인터프리터를 작성 하시겠습니까? Java는 원래 기기 및 기계 용으로 개발되었습니다. 그것은 강한 소송이었습니다. 오늘날 자바는 해석 과정의 비 효율성으로 인해 진정한 이점이 없기 때문에이 답변을 읽을 때 명심하십시오. 우리가 계속 사용하는 모델 일뿐입니다.
그레이트 덕

1
가상 머신 무엇인지 이해하지 못하는 것 같습니다 . 기계입니다. 네이티브 코드 컴파일러 (및 JVM의 경우)가있는 하드웨어에서 구현 될 수 있습니다. '가상'부분은 여기서 중요한 것입니다. 당신은 본질적으로 그 아키텍처를 다른 것 위에 모방 합니다. x86에서 실행하기 위해 8088 에뮬레이터를 작성했다고 가정 해보십시오. 이전 8088 코드를 x86으로 포팅하지 않고 에뮬레이트 플랫폼에서 실행하면됩니다. JVM은 다른 플랫폼 과 마찬가지로 대상 머신입니다. 차이점 은 다른 플랫폼 에서 실행됩니다 .
Jared Smith

7
@TheGreatDuck 해석 과정? 오늘날 대부분의 JVM은 기계 코드로 적시에 컴파일됩니다. "통역"은 요즘 꽤 광범위한 용어입니다. CPU 자체는 x86 코드를 자체 내부 마이크로 코드로 "해석" 하며 효율성 을 향상시키는 데 사용됩니다 . 최신 인텔 CPU는 일반적으로 통역사들에게도 매우 적합합니다 (물론 입증하고자하는 것을 증명할 벤치 마크를 찾을 수는 있지만).
Luaan

답변:


79

논리는 JVM 바이트 코드가 Java 소스 코드보다 훨씬 간단하다는 것입니다.

컴파일러는 매우 추상적 인 수준에서 구문 분석, 의미 분석 및 코드 생성의 세 가지 기본 부분이 있다고 생각할 수 있습니다.

파싱은 코드를 읽고 컴파일러 메모리 내부의 트리 표현으로 변환하는 것으로 구성됩니다. 시맨틱 분석은이 트리를 분석하고 그 의미를 파악하며 모든 고급 구성을 하위 수준 구성으로 단순화합니다. 코드 생성은 단순화 된 트리를 가져와 평평한 출력으로 작성합니다.

바이트 코드 파일을 사용하면 파싱 단계는 재귀 (트리 구조) 소스 언어가 아닌 JIT에서 사용하는 것과 동일한 플랫 바이트 스트림 형식으로 작성되므로 크게 단순화됩니다. 또한 의미 분석의 많은 부분이 이미 Java (또는 다른 언어) 컴파일러에 의해 수행되었습니다. 따라서 코드 스트림을 읽고, 구문 분석을 최소화하고 의미 분석을 최소화 한 다음 코드 생성을 수행하기 만하면됩니다.

이로 인해 JIT의 작업이 훨씬 간단 해 지므로 실행 속도가 훨씬 빨라지며 이론적으로 단일 소스 크로스 플랫폼 코드를 작성할 수있는 고급 메타 데이터 및 의미 정보를 보존 할 수 있습니다.


7
SafeTCL과 같은 애플릿 배포에 대한 다른 초기 시도 중 일부는 실제로 소스 코드를 배포했습니다. Java가 간단하고 엄격하게 지정된 바이트 코드를 사용 하면 프로그램 검증 이 훨씬 다루기 쉽고 해결하기 어려운 문제였습니다. p-code와 같은 바이트 코드는 이미 이식성 문제에 대한 솔루션의 일부로 알려져있었습니다 (그리고 ANDF는 당시 개발되었을 것입니다).
Toby Speight

9
정확하게. 바이트 코드-> 기계 코드 단계 때문에 Java 시작 시간은 이미 약간의 문제입니다. (사소하지 않은) 프로젝트에서 javac를 실행 한 다음 시작할 때마다 전체 Java-> 머신 코드를 수행한다고 상상해보십시오.
Paul Draper

24
또 다른 큰 이점이 있습니다. 언젠가 우리 모두가 가상의 새로운 언어로 바꾸고 싶다면- "Scala"라고 부르십시오-우리는 수십 개의 스칼라가 아닌 하나의 스칼라-> 바이트 코드 컴파일러 만 작성하면됩니다-> 기계 코드 컴파일러. 보너스로 모든 JVM의 플랫폼 별 최적화가 무료로 제공됩니다.
BlueRaja-대니 Pflughoeft

8
테일 호출 최적화와 같은 일부는 여전히 JVM 바이트 코드에서 불가능합니다. 나는 이것이 JVM으로 컴파일되는 기능적 언어를 크게 손상 시킨다는 것을 기억합니다.
JDługosz

8
@ JDługosz right : 불행히도 JVM은 아주 약간의 제한 / 디자인 관용구를 부과하지만, 명령형 언어에서 오는 경우 완벽하게 자연 스러울 수 있지만 근본적으로 작동하는 언어의 컴파일러를 작성하려는 경우 상당히 인공적인 방해물이 될 수 있습니다 다른. 따라서 미래 언어 작업 재사용에 관한 한 LLVM이 더 나은 목표라고 생각합니다. 한계도 있지만 현재 (그리고 미래에는 아마도 시간이 지남) 프로세서의 한계와 거의 일치합니다.
leftaroundabout

27

컴파일러 / 런타임 디자인에서 여러 가지 종류의 중간 표현이 점점 보편화되고 있습니다.

Java의 경우 처음에는 이식성 이 가장 큰 이유 중 하나는 Java 입니다 . Java는 처음에는 "Write Once, Run Anywhere"로 많이 판매되었습니다. 소스 코드를 배포하고 다른 컴파일러를 사용하여 다른 플랫폼을 대상으로이를 수행 할 수 있지만 몇 가지 단점이 있습니다.

  • 컴파일러는 언어의 모든 편의 구문을 이해해야하는 복잡한 도구입니다. 바이트 코드는 사람이 읽을 수있는 소스보다 기계 실행 코드에 더 가깝기 때문에 더 간단한 언어 일 수 있습니다. 이것은 다음을 의미합니다.
    • 바이트 코드 실행에 비해 컴파일 속도가 느릴 수 있습니다
    • 다른 플랫폼을 대상으로하는 컴파일러는 다른 동작을 생성하거나 언어 변경을 따라 가지 못할 수 있습니다.
    • 새로운 플랫폼을위한 컴파일러를 생성하는 것은 해당 플랫폼을위한 VM (또는 바이트 코드-네이티브 컴파일러)을 생성하는 것보다 훨씬 어렵습니다.
  • 소스 코드 배포가 항상 바람직한 것은 아닙니다. 바이트 코드는 리버스 엔지니어링에 대한 보호 기능을 제공합니다 (고의적으로 난독 화되지 않는 한 여전히 디 컴파일하는 것이 여전히 쉽지만)

중간 표현의 다른 장점은 다음과 같습니다.

  • 최적화 : 바이트 코드에서 패턴을 발견하고 더 빠른 등가물로 컴파일하거나 프로그램이 실행될 때 특별한 경우에 최적화 할 수 있습니다 ( "JIT"또는 "Just In Time"컴파일러 사용)
  • 동일한 VM에서 여러 언어 간의 상호 운용성 이것은 JVM (예 : Scala)에서 대중화되었으며 .net 프레임 워크의 명확한 목표입니다.

1
자바는 또한 임베디드 시스템을 지향했다. 이러한 시스템에서 하드웨어에는 몇 가지 메모리 및 CPU 제약이있었습니다.
Laiv

컴파일러는 먼저 Java 소스 코드를 바이트 코드로 컴파일 한 다음 바이트 코드를 기계 코드로 컴파일하는 방식으로 개발할 수 있습니까? 언급 한 대부분의 단점을 제거합니까?
Sher10ck

@ Sher10ck 예, AFAIK는 JVM 바이트 코드를 특정 아키텍처에 대한 기계 명령어로 정적으로 변환하는 컴파일러를 작성하는 것이 가능합니다. 그러나 배포자에 대한 추가 노력이나 사용자가 처음 사용할 수있는 시간을 능가 할만큼 성능이 개선 된 경우에만 의미가 있습니다. 저전력 임베디드 시스템이 도움이 될 수 있습니다. 최신 PC를 다운로드하여 여러 가지 다른 프로그램을 실행하면 잘 조정 된 JIT를 사용하는 것이 좋습니다. 나는 안드로이드 가이 방향으로 어딘가에 있다고 생각하지만 세부 사항을 모른다.
IMSoP

8

왜 우리가 소스 코드를 배포하지 않는지 궁금해하는 것 같습니다. 우리는 왜 기계 코드를 배포하지 않습니까?

분명히 대답은 Java가 의도적으로 코드가 실행될 기계가 무엇인지 알지 못한다는 것입니다. 데스크톱, 수퍼 컴퓨터, 전화 또는 그 밖의 모든 것이 될 수 있습니다. Java는 로컬 JVM 컴파일러가 작업을 수행 할 공간을 남겨 둡니다. 코드의 이식성을 높이는 것 외에도 컴파일러가 머신 별 최적화 (있는 경우)를 활용하거나 그렇지 않은 경우 여전히 작동하는 코드를 생성하는 등의 작업을 수행 할 수 있다는 이점이 있습니다. SSE 명령어 또는 하드웨어 가속 과 같은 것은 명령어를 지원하는 머신에서만 사용할 수 있습니다.

이러한 관점에서 볼 때 원시 소스 코드보다 바이트 코드를 사용하는 이유가 더 명확합니다. 원시 기계 언어에 최대한 가까이 가면 다음과 같은 기계 코드의 장점을 실현하거나 부분적으로 실현할 수 있습니다.

  • 일부 컴파일 및 분석이 이미 완료되어 시작 시간이 단축됩니다.
  • 바이트 코드 형식에는 배포 파일 서명을위한 기본 제공 메커니즘이 있으므로 보안 (소스는 규칙에 따라이 작업을 수행 할 수 있지만이를 수행하는 메커니즘은 바이트 코드와 같은 방식으로 기본 제공되지는 않음)입니다.

더 빠른 실행에 대해서는 언급하지 않습니다. 소스 코드와 바이트 코드는 실제 실행을 위해 동일한 머신 코드로 이론적으로 완전히 컴파일되거나 컴파일 될 수 있습니다.

또한 바이트 코드를 사용하면 기계 코드를 약간 개선 할 수 있습니다. 물론 앞에서 언급 한 플랫폼 독립성 및 하드웨어 별 최적화가 있지만 이전 코드에서 새로운 실행 경로를 생성하기 위해 JVM 컴파일러를 서비스하는 것과 같은 것도 있습니다. 이는 보안 문제를 패치하거나 새로운 최적화가 발견 된 경우 또는 새로운 하드웨어 지침을 활용하기위한 것일 수 있습니다. 실제로 버그를 노출시킬 수 있기 때문에 이러한 방식으로 큰 변화를 보는 것은 드물지만 가능하며 항상 작은 방식으로 발생하는 일입니다.


8

여기에는 적어도 두 가지 가능한 질문이있는 것 같습니다. 하나는 일반적으로 컴파일러에 관한 것이며 Java는 기본적으로 장르의 예일뿐입니다. 다른 하나는 Java가 사용하는 특정 바이트 코드에 대해 더 구체적입니다.

일반적으로 컴파일러

먼저 일반적인 질문을 생각해 봅시다 : 왜 컴파일러가 특정 프로세서에서 실행되도록 소스 코드를 컴파일하는 과정에서 중간 표현을 사용합니까?

복잡성 감소

이에 대한 한 가지 대답은 매우 간단합니다. O (N * M) 문제를 O (N + M) 문제로 변환합니다.

N 개의 소스 언어와 M 개의 타겟이 주어지고 각 컴파일러가 완전히 독립적 인 경우 모든 소스를 모든 타겟으로 변환하려면 N * M 컴파일러가 필요합니다 ( "target"은 프로세서 및 OS).

그러나 모든 컴파일러가 공통 중간 표현에 동의하는 경우 소스 언어를 중간 표현으로 변환하는 N 컴파일러 프런트 엔드와 중간 표현을 특정 대상에 적합한 것으로 변환하는 M 컴파일러 백 엔드를 가질 수 있습니다.

문제 세분화

더 나은 방법은 문제를 두 개 정도의 독점 도메인으로 분리하는 것입니다. 언어 디자인, 구문 분석 및 이와 유사한 것들에 대해 알고 / 관리하는 사람들은 컴파일러 프론트 엔드에 집중할 수있는 반면, 명령어 세트, 프로세서 디자인 및 이와 유사한 것들에 대해 아는 사람들은 백엔드에 집중할 수 있습니다.

예를 들어 LLVM과 같은 경우 다양한 언어에 대한 많은 프런트 엔드가 있습니다. 또한 다양한 프로세서를위한 백엔드도 있습니다. 언어 담당자는 자신의 언어에 맞는 새로운 프런트 엔드를 작성하고 많은 목표를 신속하게 지원할 수 있습니다. 프로세서 담당자는 언어 디자인, 구문 분석 등을 처리하지 않고도 대상에 대한 새로운 백엔드를 작성할 수 있습니다.

컴파일러를 프론트 엔드와 백엔드로 분리하고, 둘 사이의 통신을위한 중간 표현은 Java에서 독창적이지 않습니다. Java가 등장하기 훨씬 전부터 오랜 시간 동안 꽤 일반적인 관행이었습니다.

분포 모델

Java가 이와 관련하여 새로운 것을 추가 한 범위에서는 배포 모델이었습니다. 특히 컴파일러가 내부적으로 프론트 엔드 및 백엔드로 분리되어 있지만 일반적으로 단일 제품으로 배포되었습니다. 예를 들어, Microsoft C 컴파일러를 구입 한 경우 내부적으로 "C1"및 "C2"가 각각 프런트 엔드 및 백엔드 였지만 구입 한 것은 "Microsoft C"로 조각 (둘 사이의 작업을 조정 한 "컴파일러 드라이버"). 컴파일러는 두 가지로 구성되었지만 컴파일러를 사용하는 일반 개발자에게는 소스 코드에서 객체 코드로 변환 된 단일 항목으로, 그 사이에는 아무것도 보이지 않습니다.

대신 Java는 Java Development Kit에서 프론트 엔드를, Java Virtual Machine에서 백엔드를 분배했습니다. 모든 Java 사용자에게는 사용중인 시스템을 대상으로하는 컴파일러 백엔드가있었습니다. Java 개발자는 코드를 중간 형식으로 배포 했으므로 사용자가 코드를로드 할 때 JVM은 특정 시스템에서 코드를 실행하는 데 필요한 모든 작업을 수행했습니다.

전례

이 배포 모델도 완전히 새로운 것은 아닙니다. 예를 들어, UCSD P 시스템은 비슷하게 작동했습니다. 컴파일러 프론트 엔드는 P 코드를 생성했으며, P 시스템의 각 사본에는 특정 대상에서 P 코드를 실행하는 데 필요한 가상 머신이 포함되어있었습니다 1 .

자바 바이트 코드

Java 바이트 코드는 P 코드와 매우 유사합니다. 기본적으로 상당히 간단한 기계에 대한 지침 입니다. 이 머신은 기존 머신을 추상화 한 것이므로 거의 모든 특정 대상으로 빠르게 변환하는 것이 매우 쉽습니다. 원래 의도는 P-System과 마찬가지로 바이트 코드를 해석하는 것이기 때문에 번역의 용이성이 중요했습니다 (그렇기 때문에 초기 구현 방식과 정확히 동일합니다).

강점

Java 바이트 코드는 컴파일러 프론트 엔드가 쉽게 생성 할 수 있습니다. 예를 들어 표현을 나타내는 상당히 전형적인 트리가있는 경우 일반적으로 트리를 순회하고 각 노드에서 찾은 것에서 직접 코드를 생성하는 것이 매우 쉽습니다.

Java 바이트 코드는 대부분의 경우 대부분의 일반적인 프로세서 (특히 Sun이 Java를 설계 할 때 판매 한 SPARC와 같은 대부분의 RISC 프로세서)의 소스 코드 나 머신 코드보다 훨씬 컴팩트합니다. Java의 주요 목적 중 하나는 대부분의 사람들이 전화선을 통해 모뎀을 통해 28.8시에 전화를 통해 모뎀에 접속할 때 애플릿 (실행 전에 다운로드 될 웹 페이지에 포함 된 코드)을 지원하는 것이기 때문에 특히 중요했습니다 .8 초당 킬로 비트 (물론, 더 오래되고 느린 모뎀을 사용하는 사람들이 여전히 많음).

약점

Java 바이트 코드의 주요 약점은 특히 표현력이 없다는 것입니다. Java에 존재하는 개념을 잘 표현할 수는 있지만 Java에 포함되지 않은 개념을 표현하는 데 거의 효과가 없습니다. 마찬가지로 대부분의 컴퓨터에서 바이트 코드를 실행하는 것이 쉽지만 특정 컴퓨터를 최대한 활용하는 방식으로 바이트 코드를 실행하는 것이 훨씬 어렵습니다.

예를 들어, Java 바이트 코드를 실제로 최적화하려면 기본적으로 리버스 엔지니어링을 수행하여 기계 코드와 같은 표현에서 역으로 변환하고 SSA 명령어 (또는 유사한 것)로 되돌립니다 2 . 그런 다음 SSA 명령어를 조작하여 최적화를 수행 한 다음 실제로 관심있는 아키텍처를 대상으로하는 무언가로 변환합니다. 그러나이 복잡한 프로세스를 사용하더라도 Java와 관련이없는 일부 개념은 일부 소스 언어에서 가장 일반적인 기계에서 최적으로 실행되는 기계 코드로 변환하기 어렵다는 것을 표현하기가 어렵습니다.

요약

일반적으로 중간 표현을 사용하는 이유를 묻는 경우 다음 두 가지 주요 요인이 있습니다.

  1. O (N * M) 문제를 O (N + M) 문제로 줄이고
  2. 문제를보다 관리하기 쉬운 부분으로 나눕니다.

Java 바이트 코드의 세부 사항에 대해 질문하고 왜 다른 특정 코드 대신이 특정 표현을 선택한지에 대한 답은 원래 원래 의도와 당시 웹의 한계로 크게 돌아 왔습니다. 다음 우선 순위로 이어집니다.

  1. 컴팩트 한 표현.
  2. 빠르고 쉽게 해독하고 실행할 수 있습니다.
  3. 대부분의 일반 컴퓨터에서 빠르고 쉽게 구현할 수 있습니다.

많은 언어를 표현하거나 다양한 대상에서 최적으로 실행할 수있는 것은 우선 순위가 전혀 고려되지 않은 경우 우선 순위가 훨씬 낮았습니다.


  1. 그렇다면 왜 P- 시스템을 잊었을까요? 대부분 가격 상황. P- 시스템은 Apple II, Commodore SuperPets 등에서 꽤 괜찮게 판매되었습니다. IBM PC가 나왔을 때 P- 시스템은 지원되는 OS 였지만 MS-DOS 비용은 저렴했습니다 (대부분의 사람들의 입장에서 볼 때 무료로 제공됨). Microsoft와 IBM (다른 업체들)이 작성한 것이기 때문에 더 많은 프로그램을 빠르게 이용할 수있었습니다.
  2. 예를 들어, 이것이 Soot의 작동 방식입니다.

웹 애플릿과 매우 밀접한 관련이 있습니다. 원래 의도는 RPC가 함수 호출을 배포하고 CORBA가 개체를 배포하는 것과 같은 방식으로 코드를 어플라이언스에 배포하는 것입니다.
ninjalj

2
이것은 훌륭한 답변이며, 다른 중간 표현이 어떻게 다른 트레이드 오프를 만드는지에 대한 좋은 통찰력입니다. :)
IMSoP

@ninjalj : 정말 오크였습니다. 그것이 자바로 변모했을 때, 나는 셋톱 박스 (및 유사한) 아이디어가 보류되었다고 생각합니다 (오크와 자바가 똑같다는 정당한 주장이 있음을 인정하는 것은 처음이지만).
Jerry Coffin

@TobySpeight : 예, 표현이 더 적합 할 것입니다. 감사.
Jerry Coffin

0

다른 사람들이 지적한 이점 외에도 바이트 코드는 훨씬 작아서 배포 및 업데이트가 쉽고 대상 환경에서 더 적은 공간을 차지합니다. 이것은 공간 제약이 많은 환경에서 특히 중요합니다.

또한 저작권이있는 소스 코드를보다 쉽게 ​​보호 할 수 있습니다.


2
Java (및 .NET) 바이트 코드는 합리적으로 읽기 쉬운 소스로 다시 쉽게 변환 할 수 있으므로 이름을 엉망으로 만드는 제품과 때로는 더 어렵게 만드는 기타 정보가 있습니다. 웹 브라우저의 바이트 코드 설정일 수 있습니다.
LnxPrgr3

0

바이트 코드에서 기계 코드로 컴파일하는 것이 원래 코드를 기계 코드로 적시에 해석하는 것보다 빠릅니다. 그러나 애플리케이션을 크로스 플랫폼으로 만들려면 해석이 필요합니다. 왜냐하면 모든 플랫폼에서 원본 코드를 변경하지 않고 준비 (컴파일)없이 사용하고 싶기 때문입니다. 따라서 먼저 javac가 소스를 바이트 코드로 컴파일 한 다음이 바이트 코드를 어디에서나 실행할 수 있으며 Java Virtual Machine에서 더 빠르게 기계 코드를 해석합니다. 답은 시간을 절약 해줍니다.


0

원래 JVM은 순수한 인터프리터 였습니다. 그리고 당신이 통역하는 언어가 가능한 한 단순 하다면 가장 훌륭한 통역사를 얻게 됩니다. 바이트 코드의 목표는 런타임 환경에 효율적으로 해석 가능한 입력을 제공하는 것입니다. 이 단일 결정으로 Java는 성능에 의해 판단되는대로 해석 된 언어보다 컴파일 된 언어에 더 가깝게 배치되었습니다.

나중에 야 해석 JVM의 성능이 여전히 빨라 졌다는 사실이 밝혀 지자 사람들은 적절한 적시 컴파일러를 만들려는 노력에 투자했습니다. 이로 인해 C 및 C ++와 같은 더 빠른 언어와의 격차가 다소 줄어 들었습니다. (그러나 일부 Java 고유 속도 문제는 여전히 남아 있으므로 잘 작성된 C 코드뿐만 아니라 성능이 우수한 Java 환경을 얻지 못할 것입니다.)

물론, 손에 적시 (just-in-time) 컴파일 기술을, 우리는 할 수 실제로 배포하는 소스 코드로 돌아가, 단지 인 타임 머신 코드로 컴파일. 그러나 이렇게하면 코드의 모든 관련 부분이 컴파일 될 때까지 시작 성능이 크게 저하됩니다. 바이트 코드는 동등한 Java 코드보다 구문 분석하는 것이 훨씬 간단하기 때문에 여전히 중요한 도움이됩니다.


downvoter가 이유를 설명해 주시겠습니까 ?
cmaster

-5

텍스트 소스 코드는 사람이 쉽게 읽고 수정할 수있는 구조입니다 .

바이트 코드는 기계 가 쉽게 읽고 실행할 수있는 구조 입니다.

모든 JVM이 코드로 수행하는 작업을 읽고 실행하므로 바이트 코드는 JVM에서 사용하기에 더 적합합니다.

아직 예가 없었습니다. 바보 의사의 예 :

//Source code
i += 1 + 5 * 2 + x;

// Byte code
i += 11, i += x
____

//Source code
i = sin(1);

// Byte code
i = 0.8414709848
_____

//Source code
i = sin(x)^2+cos(x)^2;

// Byte code (actually that one isn't true)
i = 1

물론 바이트 코드는 최적화에 관한 것이 아닙니다. 그 중 상당 부분은 메소드가 "foo"를 참조 할 때 파일의 어딘가에 "foo"라는 멤버가 클래스에 포함되어 있는지 확인하는 것과 같이 복잡한 규칙에 신경 쓰지 않고 코드를 실행할 수 있다는 것입니다.


2
그 바이트 코드 "예"는 사람이 읽을 수 있습니다. 그것은 바이트 코드가 아닙니다. 이것은 오해의 소지가 있으며 질문 된 내용을 다루지 않습니다.
와일드 카드

@Wildcard 당신은이 포럼이 인간에 의해 읽혀 졌다는 것을 놓쳤을 수도 있습니다. 그렇기 때문에 내용을 사람이 읽을 수있는 형식으로 넣었습니다. 포럼이 소프트웨어 엔지니어링에 관한 것이므로 독자에게 간단한 추상화의 개념을 이해하도록 요구하는 것은 그리 많이 요구되지 않습니다.
피터

사람이 읽을 수있는 형식은 바이트 코드가 아닌 소스 코드입니다. 미리 계산 된 표현식, NOT 바이트 코드로 소스 코드를 설명하고 있습니다. 그리고 이것은 사람이 읽을 수있는 포럼이라는 것을 놓치지 않았습니다. 당신은 저가 아닌 바이트 코드의 예를 포함하지 않았다는 이유로 다른 응답자를 비난 한 사람입니다. 당신이 말하는 그래서, "나는 아직 사례가 없었다 통지"다음 줄로 진행 이 아닌 전혀 바이트 코드를 설명하지 않는 -Examples합니다. 그리고 이것은 여전히 ​​질문을 다루지 않습니다. 질문을 다시 읽으십시오.
와일드 카드
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.