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


14

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