2014-12-09 1 views
1

바인딩 : 클래스의컴파일 시간과 실행 시간을 내 이해에 따르면 메소드 오버로딩과 오버 라이딩

, 개인 최종 정적 메서드는 컴파일 시간에 결정 호출되는 방법 바인딩 시간 즉 컴파일하십시오.

그러나 비공개 인스턴스 메서드 호출은 런타임에 결정됩니다.

내 모든 문제를 해결하는 데 사용됩니다. 그러나, 나는 위의 진술이 올바른 결과를 도출하지 못하는 몇 가지 문제에 갇혀있다. 그것은주고있다

class Item 
{ 
    Integer size; 
    Item(Integer size) 
    { 
     this.size=size; 
    } 
    public boolean equals(Item item2) //not overriding the method of Object class 
    { 
     if(this==item2) 
     return true; 
     return this.size.equals(item2.size); 
    } 

    } 

public class Test 
{ 
    public static void main(String[] args) 
    { 
     Item itemA= new Item(10); 
     Item itemB= new Item(10); 
     Object itemC=itemA; 
     System.out.println("|"+ itemA.equals(itemB) + "|" + itemC.equals(itemB)+ "|"); 
    } 

} 

출력 : : 여기

는 코드 | 참 | 거짓 |

출력 예상 : | true | true | 여기

class Itemequals 방법 Objectequals 메소드를 오버라이드하지 않고, 과부하 때문에 equals 방법의 다른 방법 시그너처 일어나고있다.

질문 : itemC.equals(itemB) 호출에서 Object 클래스의 equals 메서드가 호출되는 이유는 무엇입니까? 나에 따르면

: itemC하는 런타임에서 class Item의 목적을 가지고있다, 따라서 Item classequals은 전화를받을 것이다. 런타임에는 Item class에 두 개의 equals 메소드가 있고, 하나는 자체이며 다른 하나는 Object 클래스에서 상속됩니다. 따라서 equals(Item)에 대한 호출이기 때문에 equals(Object) 대신 equals(Item)이 호출되어야합니다.

정확히 내가 누락 된 개념은 무엇입니까?

+0

을 자바를 컴파일하기 때문에, itemC.equals(itemB)Object 클래스의 equals 메소드를 호출 다른 말로하면 (멀티) 메소드는 더 이상 논리적으로 단일 클래스에 속하지 않습니다. –

답변

0

질문 : 호출 항목 C.equals (itemB)에서 Object 클래스의 equals 메서드가 호출되는 이유는 무엇입니까?

itemC의 컴파일 타임 유형은 Object입니다.

겹쳐은 대상체의 실제 유형에 기초하여 실행 시간에 수행되지만, 과부하가 타겟 식의 컴파일 - 시간 타입에 기초하여 컴파일 시간에 수행된다.

당신이 관련된 두 메서드 호출 볼 수 있습니다 javap -c -v Test 사용하는 경우 :

상수 풀 :

... 
#6 = Methodref #2.#32 // Item.equals:(LItem;)Z 
#7 = Methodref #16.#33 // java/lang/Object.equals:(Ljava/lang/Object;)Z 
... 

는 그 다음 main 방법 :

33: invokevirtual #6 // Method Item.equals:(LItem;)Z 
... 
40: invokevirtual #7 // Method java/lang/Object.equals:(Ljava/lang/Object;)Z 

는 그래서는 서명을 보여줍니다 호출중인 메소드에 대해서는입니다. 어떤 구현의이 실행되는지는 실행 시간 유형에 따라 다릅니다.따라서 equals(Object)Item으로 대체하면 itemC.equals(itemA)에 대한 재정의가 호출됩니다.

+0

그래서 컴파일 타임에'itemC.equals (itemB)'호출이 해결되고'Object' 클래스의'equals' 메소드에 바인드된다는 것을 말하고 계십니까? 컴파일 할 때'itemC'는'Object' 타입이고 실행시에 저장할 객체를 알지 못하고'itemC.equals'에 대해 오버로드가 발생하는 곳을 알지 못합니다 –

+0

@VikasMangal : 오버로드 * 만 * 사용 컴파일 시간 정보. 'itemC'의 타입은'Object'입니다. 'itemA'의 타입은'Item'이므로 컴파일러는 적절한'equals' 메소드를 찾습니다. 'equals (Object)'만이 여기에있는 유일한 가능성입니다 (메소드 서명이 유효하도록'Item'에서'Object' 로의 암묵적인 변환이 있습니다), 그래서 그것이 사용됩니다. –

+0

Item 및 Test를 컴파일하고 실행할 수 있습니다. 그런 다음 Item.equals()를 변경하여 Object 인수를 가지며 Item 만 컴파일하고 실행합니다. 인수 클래스를 Item으로 다시 변경하고 Item 만 컴파일하고 실행하십시오. 컴파일러는 테스트 컴파일 시간에 무엇을 결정 했습니까 ?? – laune

0

오버로드는 런타임이 아닌 컴파일 타임에 결정됩니다. 따라서 itemC 변수의 유형이 Object이기 때문에 itemC.equals(itemB)은 메서드를 Object이라고 호출합니다.

0

발췌문 등록 위의 진술에 따라 overloading

When a method is invoked (§15.12), the number of actual arguments (and any explicit type 
arguments) and the compile-time types of the arguments are used, at compile time, to determine the 
signature of the method that will be invoked (§15.12.2). If the method that is to be invoked is an 
instance method, the actual method to be invoked will be determined at run time, using dynamic method 
lookup (§15.12.4). 

jls에서에서 다음 만 기대가 정확하면 유형 itemCObject

관련 문제