2014-09-22 3 views
0

상속과 타입 캐스팅이 혼합되면 약간 혼란 스럽습니다. 상속에서 올바른 메서드와 변수를 선택할 때 Java 컴파일러가 따르는 규칙을 이해하고 싶습니다.자바 컴파일러는 어떻게 상속에서 올바른 메소드와 변수를 선택합니까?

변수와 같은

내가 읽고 뭔가가 컴파일 타임에 바인딩 및 방법은 런타임에 바인딩됩니다.

두번째는 stackoverflow 내지 (@ 존 스키트)

과부하 해상도 (호출되는 메소드 서명) 모두의 컴파일 - 시간 타입에 기초하여, 컴파일 시간에 결정된다 메서드 타겟 및 인수 표현식

해당 메서드 서명 (을 오버라이드)의 구현은 실행시 대상 객체의 실제 유형을 기반으로합니다.

하지만 문제는 특정 상황에 대한 설명이며 예외 처리와 같은 다른 요소를 고려할 때 일반적인 절차를 따르지 않는 것이 문제입니다.

이것은 좋지 않을 수도 있지만 메서드와 변수가 모두 무시됩니다 (static 변수의 경우 숨김).

자바 컴파일러가 컴파일 할 때 어떤 메소드/변수가 호출되어야 하는지를 선택해야한다면 어떤 알고리즘을 따르겠습니까? 마찬가지로 런타임시 Java 컴파일러가 사용할 알고리즘은 무엇입니까 (참조가 사용되는 객체의 실제 유형에 기반)?

+0

예외 처리는 과부하 해결의 일부가 아니지만 (선택한 과부하가 유효하지 않을 수도 있음), 변수가 덮어 쓰여지지 않고 숨겨져 있습니다. 자세한 규칙을 찾고 있다면 JLS를 읽어 보시기 바랍니다. http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12 –

+0

컴파일러는 선택하지 않으며 컴파일 타임에 메소드를 호출하지 않습니다. 가상 메소드 테이블을 사용하여 런타임에이를 수행하는 것은 JVM의 책임입니다. –

+0

"메소드와 변수가 모두 무시된다고 가정하십시오." "변수 무시"와 같은 것은 없습니다. @JonSkeet이 "과부하 해결"이라고 부르는 것은 _signature_ 메서드를 선택하는 것을 의미합니다. 서명은 메소드 이름의 확장 된 형식입니다. foo (int i)로 선언 된 메서드는 foo (String s)로 선언 된 메서드와 다른 서명 (name)을가집니다. 컴파일러는 컴파일 타임에 메소드 호출 표현식의 메소드 서명을 항상 알 수 있습니다. _Overriding_는 부모 클래스와 하위 클래스가 모두 동일한 _ 시그니처가있는 메소드를 선언 할 때 발생합니다. 그것이 런타임에 해결되는 것입니다. –

답변

5

모든 메서드 서명과 변수는 컴파일 타임에 확인되지만 실제 메서드 호출은 런타임 중에 완료/해결됩니다. 예를 들어

: 당신이 a.doSomething(); 호출 할 때

이제
class A { 
int i=5; 
public void doSomething(){ 
//print "in A" 
} 
} 

class B extends A{ 
int i=10;  
public void doSomething(){ 
// print "in B" 
} 

public static void main(String[] args){ 
A a = new B(); 
a.doSomething(); 
} 
} 

, 컴파일시 컴파일러는 doSomething()는 클래스 A (좌 참조)에 정의되어 있는지 여부를 확인합니다. 메서드가 클래스 B에 대해서도 정의되어 있는지 여부조차 신경 쓰지 않습니다. 메서드가 B에 없더라도 프로그램은 올바르게 컴파일됩니다.

런타임 중에 JVM은 객체 유형 (사례의 경우 B)을 기반으로 호출 할 메소드를 동적으로 결정합니다.

따라서 "in B"이 인쇄됩니다.

이제 필드로 돌아옵니다. 필드에 대한 액세스는 컴파일하는 동안 해결됩니다. 따라서 컴파일 타임 동안 필드가 존재하지 않으면 컴파일이 실패합니다. 필드는 참조 유형에 따라 호출됩니다. 따라서 a.i은 컴파일시 필드가 확인되었으므로 5 (A's 값은 i)입니다. 따라서, 메소드 호출은 런타임 중에 해결되고, 컴파일 타임 동안 필드가 점검/해결 될 때 컴파일 타임에 시그니처가 필요/검사됩니다.

+0

메소드 호출과 필드 액세스 간의 런타임 동작의 차이점을 명확히해야합니다. –

+0

@SotiriosDelimanolis - 완료 .. – TheLostMind