2013-05-15 2 views
4

출력의 이유를 알려주십시오. 우리는 B의 객체의 참조 ID를 얻을 것이다 b.getx().x 10의 값을 받아야하지만이 프로그램을 실행하면 출력이 5핵심 Java 동적 바인딩

class Base { 
    int x = 5; 
    public Base getx() { 
    return new Base(); 
    } 
} 

class Child extends Base { 
    int x = 10; 
    public Child getx() { 
    return new Child(); 
    } 

    public static void main(String ...s) { 
    Base b = new Child(); 
    System.out.println(b.getx().x); 
    } 
} 
+0

http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.11.1 –

답변

8

필드입니다 b.getx() 저 당으로

, 액세스 (메소드 호출과 달리)는 런타임 동적 디스패치의 대상이 아니며 컴파일 시간 유형을 기반으로 결정됩니다.

변수 b 그러므로 b.getx()도의 컴파일시의 형태 Baseb.getx().x이 자료의 x 필드가 아닌 자녀의의 액세스로 컴파일 될 것이다, 컴파일시의 형태 Base이다. 이것은 main 방법 javap의 출력을 조사하여 확인 :

public static void main(java.lang.String[]); 
    Code: 
    0: new #3; //class Child 
    3: dup 
    4: invokespecial #4; //Method "<init>":()V 
    7: astore_1 
    8: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream; 
    11: aload_1 
    12: invokevirtual #6; //Method Base.getx:()LBase; 
    15: getfield #7; //Field Base.x:I 
    18: invokevirtual #8; //Method java/io/PrintStream.println:(I)V 
    21: return 

당신이 b.getx().x 특별히 Base.x에 대한 getfield 명령으로 컴파일 된 것을 볼 수 있습니다.

+0

데이터 멤버가 컴파일시 바인드된다는 의미입니까? 왜냐하면 두 클래스 모두에서 int x를 제거하고 System.out.println (b.getx()); 자식 클래스 객체를 호출합니다. –

+0

@ShardaPrasadJaiswal 네,'b.getx()'의 _runtime_ 타입은'Child'가 될 것입니다.하지만 필드 접근 왼쪽에있는 표현식의 _compile-time_ 타입에만 기반한'ax' 접근에는 영향을 미치지 않습니다. 점. 'Base.x'와'Child.x'가 서로 다른 유형 (예 : 하나의'int'와 하나의'String')을 가지고 있다고 상상해보십시오 ... –

1

동적 바인딩은 기본적으로 실제로 호출되는 메서드 구현은 컴파일 타임이 아니라 런타임에 결정된다는 것을 의미합니다. 이것이 동적 바인딩이라고하는 이유입니다. 실행될 메소드는 런타임에 선택되기 때문입니다. 동적 바인딩은 후기 바인딩 (late binding)이라고도합니다.

0

동적 바인딩은 런타임에 선언을 찾는 런타임 시간 프로세스입니다. 컴파일시보다 런타임시 대체 메소드에 대한 호출을 해석하는 후기 바인딩 (late binding)이라고도합니다. 개체 지향 시스템에서 메서드 재정의 (동적 다형성)는 런타임에 수행됩니다. 한 메소드를 다른 메소드로 겹쳐 쓰면 두 메소드의 서명이 동일해야합니다.

예 :

class Animal{ 

    public void eat(){ 
     System.out.println("Animals voice"); 
    } 

public void go(){ 
     System.out.println("Animals can walk"); 
    } 

} 

class Dog extends Animal{ 

    public void go(){ 
     System.out.println("Dogs can walk and run"); 
    } 
    public void eat(){ 
     System.out.println("Dogs can eat a wide range of foods"); 
    } 
} 
1

Base b = new Child();가 런타임 해결 (런타임 다형)이 관련된 모든 방법을 그렇게 런타임 바인딩해야 ...

결합 동적 규칙입니다
public Base getx() { 
    return new Base(); 
    } 

그 줄은 기본 클래스의 새 인스턴스를 반환하고 방금 해당 인스턴스에서 variable을 호출했습니다.