자바 코드 컴 파일 과 역 컴 파일
컴 파일 과 역 컴 파일 을 소개 하기 전에 프로 그래 밍 언어(Programming Language)를 간단하게 소개 합 니 다.프로 그래 밍 언어(Programming Language)는 저급 언어(Low-level Language)와 고급 언어(High-level Language)로 나 뉜 다.
기계 언어(Machine Language)와 어 셈 블 리 언어(Assembly Language)는 저급 언어 로 컴퓨터 명령 으로 프로그램 을 직접 작성 합 니 다.
C,C++,Java,Python 등 은 고급 언어 에 속 하고 문장(Statement)으로 프로그램 을 작성 하 며 문장 은 컴퓨터 명령 의 추상 적 인 표현 이다.
예 를 들 어 같은 문 구 는 C 언어,어 셈 블 리 언어 와 기계 언어 로 다음 과 같이 표시 한다.
컴퓨터 는 숫자 만 연산 할 수 있 고 기호,소리,이미 지 는 컴퓨터 내부 에서 모두 숫자 로 표시 해 야 한다.명령 도 예외 가 아니다.위의 표 의 기계 언어 는 완전히 16 진수 로 구성 된다.최초의 프로그래머 들 은 모두 기계 언어 로 프로 그래 밍 을 했 지만 매우 번 거 로 웠 다.모든 숫자 가 무슨 뜻 을 표시 하 는 지 확인 하기 위해 대량의 표를 찾 아야 했다.작 성 된 프로그램 은 직관 적 이지 않 고 오류 가 발생 하기 쉬 웠 다.그래서 어 셈 블 리 언어 가 생 겼 다.기계 언어 에서 한 그룹의 숫자 를 보조 기호(Mnemonic)로 표시 하고 이 보조 기호 로 어 셈 블 리 프로그램 을 직접 썼 다.그리고 어 셈 블 러(Assembler)에 게 표를 찾 아 보조 기 호 를 숫자 로 바 꾸 게 하고 어 셈 블 리 언어 를 기계 언어 로 번역 했다.
그러나 어 셈 블 리 언어 는 사용 하기에 도 복잡 하고 그 다음 에 자바,C,C++등 고급 언어 가 파생 되 었 다.
뭐 공부 해요?
위 에서 언급 한 언어 는 두 가지 가 있 는데 하 나 는 저급 언어 이 고 하 나 는 고급 언어 이다.저급 언어 는 컴퓨터 가 인식 하 는 언어 이 고 고급 언어 는 프로그래머 가 인식 하 는 언어 라 는 것 을 간단하게 이해 할 수 있다.
그렇다면 어떻게 고급 언어 에서 저급 언어 로 바 꿉 니까?이 과정 은 사실 컴 파일 이다.
위의 예 를 통 해 알 수 있 듯 이 C 언어의 어구 와 저급 언어의 명령 은 간단 한 대응 관계 가 아니 라 a=b+1 이다.문 구 는 세 개의 어 셈 블 리 나 기계 명령 으로 번역 해 야 한다.이 과정 을 컴 파일(Compile)이 라 고 부 르 고 컴 파일 러(Compiler)로 완성 해 야 한다.컴 파일 러 의 기능 이 어 셈 블 리 보다 훨씬 복잡 한 것 이 분명 하 다.C 언어 로 작 성 된 프로그램 은 컴 파일 을 거 쳐 기계 명령 으로 전환 해 야 컴퓨터 에서 실 행 될 수 있 습 니 다.컴 파일 은 시간 이 좀 걸 립 니 다.이것 은 고급 언어 로 프로 그래 밍 하 는 단점 이지 만 장점 이 더 많 습 니 다.우선,C 언어 로 프로 그래 밍 하 는 것 이 더욱 쉽 고 쓴 코드 가 더욱 치밀 하 며 가 독성 이 강하 고 잘못 되면 고치 기 쉽다.
사람 이 쉽게 작성 하고 읽 으 며 유지 할 수 있 는 고급 컴퓨터 언어 로 작 성 된 소스 코드 프로그램 을 컴퓨터 가 해석 하고 실행 할 수 있 는 저급 기계 언어 로 번역 하 는 과정 은 컴 파일 하 는 것 입 니 다.이 과정 을 담당 하 는 도 구 를 컴 파일 러 라 고 합 니 다.
이제 우 리 는 컴 파일 이 무엇 인지 알 게 되 었 고 컴 파일 러 가 무엇 인지 알 게 되 었 다.서로 다른 언어 는 모두 자신의 컴 파일 러 가 있 습 니 다.자바 언어 에서 컴 파일 을 담당 하 는 컴 파일 러 는 명령 입 니 다:자바 c
javac 는 JDK 에 수 록 된 자바 언어 컴 파일 러 입 니 다.이 도 구 는 접미사 이름 이 자바 인 원본 파일 을 접미사 이름 이'class'인 자바 가상 컴퓨터 에서 실행 할 수 있 는 바이트 코드 로 컴 파일 할 수 있 습 니 다.
Hello World.java 파일 을 다 쓴 후에,우 리 는 javac Hello World.java 명령 을 사용 하여 Hello World.class 파일 을 생 성 할 수 있 습 니 다.이 class 형식의 파일 은 JVM 에서 식별 할 수 있 는 파일 입 니 다.일반적으로 우 리 는 이 과정 을 자바 언어의 컴 파일 이 라 고 생각한다.사실 클 라 스 파일 은 기계 가 식별 할 수 있 는 언어 가 아니다.기계 가 기계 언어 만 식별 할 수 있 기 때문에 JVM 이 이런 클 라 스 파일 형식 바이트 코드 를 기계 가 식별 할 수 있 는 기계 언어 로 변환 해 야 한다.
무엇이 역 컴 파일 입 니까?
역 컴 파일 과정 은 컴 파일 과 정반 대 입 니 다.컴 파일 된 프로 그래 밍 언어 를 컴 파일 되 지 않 은 상태 로 복원 하 는 것 입 니 다.즉,프로그램 언어의 소스 코드 를 찾 는 것 입 니 다.기계 가 알 아 볼 수 있 는 언어 를 프로그래머 가 알 아 볼 수 있 는 언어 로 바 꾸 는 것 이다.자바 언어의 역 컴 파일 은 일반적으로 클 라 스 파일 을 자바 파일 로 변환 하 는 것 을 말한다.
역 컴 파일 도구 가 있 으 면 우 리 는 많은 일 을 할 수 있다.가장 중요 한 기능 은 바로 역 컴 파일 도구 가 있 으 면 우 리 는 자바 컴 파일 러 가 생 성 한 바이트 코드 를 읽 을 수 있다.바이트 코드 를 읽 으 면 무슨 소 용이 있 는 지 물 어보 고 싶다 면,나 는 책임감 있 게 너 에 게 좋 은 점 이 매우 크다 고 말 할 수 있다.예 를 들 어 나의 박문 몇 편의 전형 적 인 원리 적 인 글 은 모두 반 컴 파일 도 구 를 통 해 반 컴 파일 된 코드 분석 을 통 해 얻 은 것 이다.예 를 들 어 다 중 스 레 드(1)-Synchronized 의 실현 원 리 를 깊이 이해 하고 자바 의 매 거 진 유형-매 거 진 스 레 드 안전성 과 직렬 화 문제,자바 의 Switch 가 정형,문자 형,문자열 형의 구체 적 인 실현 디 테 일,자바 의 유형 지우 기 등 이다.나 는 최근 에 GitChat 에서 자바 문법 사탕 에 관 한 글 을 썼 는데 그 중에서 대부분 내용 은 문법 사탕 뒤의 원 리 를 역 컴 파일 도구 로 파악 했다.
자바 역 컴 파일 도구
본 고 는 주로 자바 의 역 컴 파일 도구 3 개 를 소개 한다.자바 p,jad,cfr
javap
javap 는 jdk 가 자체 적 으로 가지 고 있 는 도구 로 코드 를 역 컴 파일 할 수도 있 고 자바 컴 파일 러 가 생 성 한 바이트 코드 도 볼 수 있 습 니 다.javap 와 다른 두 개의 역 컴 파일 도구 의 가장 큰 차 이 는 그 가 만 든 파일 이 자바 파일 이 아니 라 다른 두 도구 가 코드 를 만 드 는 것 처럼 쉽게 이해 되 지 않 는 다 는 것 이다.자바 7 의 switch 가 String 을 어떻게 지원 하 는 지 분석 하려 면 다음 과 같은 소스 코드 를 컴 파일 할 수 있 습 니 다.
public class switchDemoString {
public static void main(String[] args) {
String str = "world";
switch (str) {
case "hello":
System.out.println("hello");
break;
case "world":
System.out.println("world");
break;
default:
break;
}
}
}
다음 두 명령 을 실행 합 니 다:
javac switchDemoString.java
javap -c switchDemoString.class
생 성 코드 는 다음 과 같 습 니 다:
public class com.hollis.suguar.switchDemoString {
public com.hollis.suguar.switchDemoString();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String world
2: astore_1
3: aload_1
4: astore_2
5: iconst_m1
6: istore_3
7: aload_2
8: invokevirtual #3 // Method java/lang/String.hashCode:()I
11: lookupswitch { // 2
99162322: 36
113318802: 50
default: 61
}
36: aload_2
37: ldc #4 // String hello
39: invokevirtual #5 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
42: ifeq 61
45: iconst_0
46: istore_3
47: goto 61
50: aload_2
51: ldc #2 // String world
53: invokevirtual #5 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
56: ifeq 61
59: iconst_1
60: istore_3
61: iload_3
62: lookupswitch { // 2
0: 88
1: 99
default: 110
}
88: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
91: ldc #4 // String hello
93: invokevirtual #7 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
96: goto 110
99: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
102: ldc #2 // String world
104: invokevirtual #7 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
107: goto 110
110: return
}
개인 적 으로 자바 p 는 바이트 코드 를 자바 파일 로 역 컴 파일 하지 않 고 우리 가 볼 수 있 는 바이트 코드 를 만 들 었 다 는 것 을 이해 합 니 다.사실 자바 p 에서 생 성 된 파일 은 여전히 바이트 코드 입 니 다.프로그래머 만 조금 알 아 볼 수 있 습 니 다.바이트 코드 에 대해 잘 알 고 있다 면 이상 의 코드 를 볼 수 있 습 니 다.사실은 String 을 hashcode 로 바 꾸 고 비교 하 는 것 입 니 다.개인 적 으로 일반적인 상황 에서 우 리 는 자바 p 명령 을 사용 할 때 가 많 지 않 고 보통 바이트 코드 를 볼 때 만 사용 할 수 있다 고 생각 합 니 다.그러나 바이트 코드 중간 에 노출 된 것 이 가장 완전 합 니 다.당신 은 반드시 사용 할 기회 가 있 을 것 입 니 다.예 를 들 어 제 가 synchronized 의 원 리 를 분석 할 때 자바 p 를 사용 합 니 다.javap 를 통 해 생 성 된 바이트 코드 를 통 해 synchronized 바 텀 이 ACC 에 의존 하고 있 음 을 알 게 되 었 습 니 다.SYNCHRONIZED 태그 와 Monitorenter,Monitorexit 두 가지 명령 으로 동기 화 를 실현 합 니 다.
jad
jad 는 실행 도 구 를 다운로드 하면 class 파일 에 대한 역 컴 파일 을 실현 할 수 있 는 비교적 좋 은 역 컴 파일 도구 입 니 다.아니면 위의 소스 코드 입 니까?jad 를 사용 하여 역 컴 파일 한 내용 은 다음 과 같 습 니 다.
명령:jad switchDemoString.class
public class switchDemoString
{
public switchDemoString()
{
}
public static void main(String args[])
{
String str = "world";
String s;
switch((s = str).hashCode())
{
default:
break;
case 99162322:
if(s.equals("hello"))
System.out.println("hello");
break;
case 113318802:
if(s.equals("world"))
System.out.println("world");
break;
}
}
}
봐 라,이 코드 는 틀림없이 알 아 볼 수 있 을 것 이다.왜냐하면 이것 은 표준 자바 의 소스 코드 가 아니 기 때문이다.이것 은 원래 문자열 의 switch 가 equals()와 hashCode()방법 을 통 해 이 루어 진 것 을 똑똑히 볼 수 있다.그러나 jad 는 오랫동안 업데이트 되 지 않 았 습 니 다.자바 7 에서 생 성 된 바이트 코드 를 역 컴 파일 할 때 지원 되 지 않 는 문제 가 발생 할 수 있 습 니 다.자바 8 의 lambda 표현 식 을 역 컴 파일 할 때 완전히 실 패 했 습 니 다.
CFR
jad 는 아주 좋 습 니 다.그러나 어 쩔 수 없 이 오랫동안 업데이트 되 지 않 았 기 때문에 새로운 도구 로 그 를 대체 할 수 밖 에 없습니다.CFR 은 좋 은 선택 입 니 다.jad 에 비해 그의 문법 은 약간 복잡 할 수 있 지만 다행히 그 는 work 할 수 있 습 니 다.
예 를 들 어,우 리 는 cfr 를 사용 하여 방금 코드 를 역 컴 파일 합 니 다.명령 실행 하기:
java -jar cfr_0_125.jar switchDemoString.class --decodestringswitch false
다음 코드 받 기:
public class switchDemoString {
public static void main(String[] arrstring) {
String string;
String string2 = string = "world";
int n = -1;
switch (string2.hashCode()) {
case 99162322: {
if (!string2.equals("hello")) break;
n = 0;
break;
}
case 113318802: {
if (!string2.equals("world")) break;
n = 1;
}
}
switch (n) {
case 0: {
System.out.println("hello");
break;
}
case 1: {
System.out.println("world");
break;
}
}
}
}
이 코드 를 통 해 문자열 을 얻 을 수 있 는 switch 는 equals()와 hashCode()방법 으로 이 루어 진 결론 입 니 다.Jad 에 비해 CFR 은 인자 가 많 고 방금 코드 입 니 다.다음 명령 을 사용 하면 출력 결과 가 다 릅 니 다.
java -jar cfr_0_125.jar switchDemoString.class
public class switchDemoString {
public static void main(String[] arrstring) {
String string;
switch (string = "world") {
case "hello": {
System.out.println("hello");
break;
}
case "world": {
System.out.println("world");
break;
}
}
}
}
그래서--decodestringswitch 는 switch 가 string 을 지원 하 는 디 테 일 을 디 코딩 하 는 것 을 표시 합 니 다.비슷 한 것 은 decodeenumswitch,decodefinally,decodelambdas 등 이 있다.문법 사탕 에 관 한 글 에서 저 는-decodelambda 표현 식 경찰 을 역 컴 파일 했 습 니 다.원본 코드:
public static void main(String... args) {
List<String> strList = ImmutableList.of("Hollis", " :Hollis", " :www.hollischuang.com");
strList.forEach( s -> { System.out.println(s); } );
}
java -jar cfr_0_125.jar lambdaDemo.class--decodelambdas false 컴 파일 후 코드:
public static /* varargs */ void main(String ... args) {
ImmutableList strList = ImmutableList.of((Object)"Hollis", (Object)"\u516c\u4f17\u53f7\uff1aHollis", (Object)"\u535a\u5ba2\uff1awww.hollischuang.com");
strList.forEach((Consumer<String>)LambdaMetafactory.metafactory(null, null, null, (Ljava/lang/Object;)V, lambda$main$0(java.lang.String ), (Ljava/lang/String;)V)());
}
private static /* synthetic */ void lambda$main$0(String s) {
System.out.println(s);
}
CFR 에는 또 많은 다른 매개 변수 가 있 는데 모두 다른 장면 에 사용 되 며 독 자 는 자바-jar cfr 를 사용 할 수 있 습 니 다.0_125.jar--help 에 대해 알 아 봅 니 다.여기 하나씩 소개 안 할 게 요.어떻게 역 컴 파일 을 방지 합 니까?
Class 파일 을 역 컴 파일 할 수 있 는 도구 가 있 기 때문에 개발 자 에 게 자바 프로그램 을 어떻게 보호 하 느 냐 가 매우 중요 한 도전 이 되 었 습 니 다.그러나 마 는 한 자 높 고,도 는 한 장 높다.당연히 대응 하 는 기술 이 있 지.역 컴 파일 에 대응 할 수 있 지.그러나 여기 서 한 가지 설명 을 해 야 한다.네트워크 안전 의 보호 와 마찬가지 로 아무리 노력 해도 사실은 공격 자의 원 가 를 높이 는 것 일 뿐이다.철저하게 예방 치료 할 방법 이 없다.
전형 적 인 대응 전략 은 다음 과 같은 몇 가지 가 있다.
격 리 자바 프로그램
난이도
코드 혼동
코드 를 기능 상 등가 로 바 꾸 지만 읽 기와 이해 하기 어 려 운 형식총결산
이상 은 이 글 의 모든 내용 입 니 다.본 고의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가 치 를 가지 기 를 바 랍 니 다.여러분 의 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.