자바 바이트코드

자바 바이트코드(Java bytecode)는 자바 가상 머신이 실행하는 명령어의 형태이다. 각각의 바이트코드는 1바이트로 구성되지만 몇 개의 파라미터가 사용되는 경우가 있어 총 몇 바이트로 구성되는 경우가 있다. 256개의 명령코드 모두가 사용되지는 않는다.

자바와의 관계 
자바 프로그래머가 자바 바이트코드를 꼭 인지하거나 이해할 필요는 없다. 하지만 IBM의 developerWorks journal에서 제안했듯이 "바이트코드를 이해하고 자바 컴파일러에 의해 바이트코드가 어떻게 생성될 것인지를 이해하는 것은 C나 C++ 프로그래머가 어셈블리어를 이해하는 것과 같다" 라고 볼 수 있다.

역컴파일러 
이렇듯 기계가 직접 실행하는 기계어가 아닌 중간단계인 바이트코드 형태로 변환되는 관계로 자바는 역컴파일러(逆compiler) 혹은 디컴파일러(decompiler)라고 불리는 실행코드에서 소스코드를 역으로 추출하는 프로그램에 취약한 편이다.
특히 라인정보 등의 디버깅 정보를 포함하여 컴파일 할 경우는 주석문을 제외한 거의 완전한 소스코드를 추출할 수 있다.

이에 대한 대비로 역컴파일을 어렵게 하고 만일 성공하더라도 원래의 소스 구조를 알기 힘들게 변경하는 프로그램(obfuscator) 들이 존재한다. 이 프로그램들은 주로 클래스 파일의 디버깅 정보를 제거하고 클래스명/함수명/변수명등을 임의의 단문자 형태로 치환하기 때문에 생성되는 클래스파일의 크기를 줄이는 목적으로 사용되기도 한다.

예 
다음의 자바 코드에 있다고 가정한다:

outer:
for (int i = 2; i < 1000; i++) {
    for (int j = 2; j < i; j++) {
        if (i % j == 0)
            continue outer;
    }
    System.out.println (i);
}

자바 컴파일러는 위의 자바 코드를 아래와 같은 바이트 코드로 번역한다:
0:   iconst_2
1:   istore_1
2:   iload_1
3:   sipush  1000
6:   if_icmpge       44
9:   iconst_2
10:  istore_2
11:  iload_2
12:  iload_1
13:  if_icmpge       31
16:  iload_1
17:  iload_2
18:  irem
19:  ifne    25
22:  goto    38
25:  iinc    2, 1
28:  goto    11
31:  getstatic       #84; // Field java/lang/System.out:Ljava/io/PrintStream;
34:  iload_1
35:  invokevirtual   #85; // Method java/io/PrintStream.println:(I)V
38:  iinc    1, 1
41:  goto    2
44:  return

각주

외부 링크 
  자바가상머신명세 2판
  자바 역컴파일러
  오픈소스 자바 obfuscator

자바 플랫폼
어셈블리어