컴파일러가 다른 클래스와 해당 속성에 대해 어떻게 알 수 있습니까?


14

나는 객체 지향적이고 지금까지 단일 '클래스'를 만드는 데 좋은 첫 번째 프로그래밍 언어를 작성하고 있습니다. 그러나,하자 내가 클래스가하고 싶은 말은, 말을 ClassA하고 ClassB. 이 두 사람이 서로 관련이 없다면 모든 것이 좋습니다. 그러나 say ClassAClassB--this는 두 가지 관련 질문을 제기합니다.

- 어떻게 컴파일러 노하우를 컴파일 할 때 ClassA것을 ClassB이 않는 경우, 어떻게 그것의 속성을 알고 있지, 심지어는 존재하고?

내 생각은 지금까지 한 번에 한 번에 각 클래스를 컴파일하는 대신 (예 : 스캔, 구문 분석 및 생성) 각 "파일 (실제로는 파일 자체가 아니라"클래스 ")입니다. 각각 먼저 스캔하고 구문 분석해야합니까? 그런 다음 모두 코드를 생성합니까?

답변:


13

다른 언어 (및 컴파일러)는 이것에 다르게 접근합니다.

C 패밀리에서 다른 모듈에는 오브젝트를 빌드하는 동안 사용되는 해당 헤더 파일이 있습니다. 헤더 파일은 오브젝트의 크기와 호출 될 수있는 기능 또는 메소드에 대한 정보를 제공합니다. 이를 통해 메모리 할당에 필요한 정보를 얻을 수 있으며 "방법 / 기능 / 프로 시저가 존재합니까?" 소스 자체에 액세스 할 필요가없는 단일 유닛을 컴파일 할 때 사용됩니다.

Java에서 컴파일러는 클래스 경로의 항목을 인식하고 해당 객체를 링크하여 연결합니다 (메소드가 존재하는지 확인하고 적절한 수의 인수를 갖는지 등). Java는 컴파일 될 때 알지 못하는 다른 클래스에서 런타임로드시 동적으로 링크 될 수도 있습니다. 동적 로딩의 한 예는 Class.forName 을 참조하십시오 .

두 옵션 모두 매우 유효하며 고유 한 장단점이 있습니다. 헤더 파일을 제공 하는 것은 번거롭고 DRY 위반으로 간주됩니다 . 반면에 헤더 파일이없는 경우 컴파일러와 링커에서 라이브러리를 검사 할 수 있어야합니다-.so 또는 .dll에는 객체를 올바르게 인스턴스화하거나 메소드 호출의 유효성을 검사하기에 충분한 정보가 없습니다 ( 기계에 따라 다름).


0

실제로 Java를 사용하면 IDE는 전체 프로그램을 한 번에 살펴 봅니다. ClassB가 참조 될 때 IDE 컴파일러가이를 볼 것이다. 라이브러리를 포함한 모든 것은 하나의 완전한 전체입니다. 프로그램이 준비되면 클래스 경로를 변경하고 개별 .class 파일을 교환하거나 라이브러리 버전을 전환 할 수 있습니다. IDE를 사용하지 않고 (또는 확인을 피하면서) 개별 .java 파일을 컴파일 할 수도 있습니다. 결과는 전혀 일관성을 필요로하지 않으며, 그렇지 않은 경우는 것입니다 런타임 얻을 예외. (IDE가 당신을 위해하려고하는 많은 일 중 하나는 런타임 오류를 컴파일 타임 또는 편집 시간 오류로 바꾸는 것입니다.)

C #은 거의 동일하며 Java와 C # IDE 가하는 일이 막후에서 C / C ++ 스타일 헤더를 생성한다는 점에서 C와 C ++이 실제로 다르다고 생각하지 않습니다.


Java 컴파일러는 필요한 경우 종속적 인 내용도 컴파일합니다. 당신이 한 경우에만 이런 종류의에서 런타임 예외를 얻을 정말 (예를 들어, 변화와 그 API의 소비자를 컴파일 후 API를 재 컴파일) 강제 일에 열심히 노력했다.
Donal Fellows

@DonalFellows : 문제로 인해 라이브러리가 없어졌지만 ( "하지만 모든 컴퓨터에 저장했습니다!") 실행중인 프로그램 (의도적으로 핫스왑하는 .class 파일)을 다시 컴파일합니다. 더 이상 주 프로그램과 일치하지 않는 패키지 업데이트를 예상 할 수 있지만 아직 완료하지는 않았습니다. 내가 했던 C와 .DLL의와 그의를 많이 할 (그리고 그것은 나에게했던) 년 전. 나는 당시에는 없었던 많은 보호 장치가 현재 존재한다고 믿고 믿고 있습니다.
RalphChapin

컴파일러 / 링커가 컴파일 / 링커 문제를 해결하는 방법을 아는 방법과 관련하여 IDE와 관련이 없습니다. 내가 틀렸다면 정정하십시오.하지만 IDE는 전체 문제와 완전히 직교합니다 (프로그래머의 작업을 쉽게하는 것을 제외하고). 왜? 이론적으로 IDE는 백그라운드에서 컴파일러를 사용하기 때문입니다.
Thomas Eding

@ThomasEding : 당신 말이 맞아요. 이 질문에 대답했을 때 컴파일러 / 링커에서 IDE를 분리하는 데 문제가있는 것 같습니다. 내 변명 : Java는 실행될 때까지 "링크"하지 않으므로 클래스 참조 또는 메소드 호출이 그때까지 잘못되었음을 알 수 없습니다. IDE는 실제로 내 작업을 "쉬워"하지 않으며 가능합니다. 컴파일 할 때, 링크 할 때, 그리고 실행할 때 오류를 얻기 위해 (오래 전에 FORTRAN 및 C에서) 사용했습니다. 이제 입력 할 때 거의 모든 오류가 발생하여 IDE를 컴파일러, 링커 실행기로 만듭니다. 오늘날 모든 비 런타임 오류는 IDE에서 발생합니다.
RalphChapin

0

오래된 언어는 때때로 더 엄격합니다. Java에서 가능한 것을 고려하십시오.

public interface Ifc {
    public static final Ifc MY_CONSTANT = new Implem();
}

public class Implem implements Ifc {
}

나는 위의 반 패턴을 보았고, 정말 추악합니다 (금지했을 것입니다). 두 컴파일 단위는 서로를 사용합니다. 그러나 Ifc은 컴파일 된 Implem없이 코드로 컴파일 될 수 있습니다. C .obj와 비교할 수있는 컴파일 된 코드 .class에는 "linkage information :"이라는 매개 변수가없는 constructor을 호출하는 Implem의 가져 오기가 포함되어 있습니다 Implem(). Implem 클래스는 문제없이 컴파일 될 수 있습니다. 부분적으로 ClassLoader-초기화 / 빌드 JVM 클래스 데이터를 수행하고 일부는 Java Virtual Machine 자체를 링커 로 사용하여 모두 통합합니다.

예를 들어 특정 라이브러리의 한 버전으로 컴파일하고 해당 라이브러리의 다른 버전으로 실행하면 런타임 오류가 인식됩니다.

답 : 컴파일은 컴파일 된 객체 코드 단위를 제공하는데,이 코드는 서로 연결하기 위해 코드 + 데이터 + API로 볼 수 있습니다.

컴파일러는해야 나중에 도 함께 포장을하고, 검증 연계 API를; 두 번째 단계.

이것은 짜증나고 우아해 보이지만 수학적 증거는 같은 방식으로 작동 할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.