2017-01-08 6 views
0

ArrayList<Object> arr = new ArrayList<Object>();의 배열 목록이 있다고 가정하면이 arraylist에 여러 개의 다른 객체를 채우십시오. 모든 객체는 object에서 상속받습니다. 동적 (런타임) 다형성은 Java에서 어떻게 작동합니까? 즉, JVM은 호출 할 메소드를 어떻게 알 수 있습니까?

arr.add(new Integer(1)); 
arr.add("Im a String"); 
arr.add(new SomeOtherObject); 

가 예상대로 다음 .toString() 메서드를 호출 ArrayList를 통해 루프,이 실제로 StringInteger 클래스의 오버라이드 (override) toString() 메소드를 호출, 작동 말해, 뭔지 혼란 것은 그 JVM에의 IntegerString arrayList 내부의 객체는 객체에 내재적으로 캐스팅되었으므로 JVM은 arrayList에 넣기 전에 어떤 식 으로든 다시 JVM에 알리는 방법을 알고 있습니까? 미안이 질문에 분명한 대답이있는 경우이 나던은 나에게 많은 의미가있는 것처럼 보입니다

+0

주조가 원시적 형의 경우를 제외하고 변환되지 않습니다. – EJP

답변

4

각 개체의 유형은 해당 개체의 머리글에 저장되어 있습니다. 참조을 개체에 캐스팅하면 어떤 방식으로도 개체가 변경되지 않습니다.

예를 들어 .toString을 호출하면 클래스 설명에서 호출 할 메서드를 찾습니다. 참고 : 코드를 최적화 할 수있는 경우 매번이 작업을 수행 할 필요는 없습니다.

1

Fooclass이고 arr이라고하는 ArrayList<Object>이 있다고 가정 해 봅시다. arr.add(new Foo())라고하면 Fooclass의 새 개체가 arr에 새 요소로 추가됩니다. 이는 Fooclass이고 Object에서 상속되기 때문에 가능합니다. 그러나 FooObject에서 상속 되더라도 개체는 Foo입니다. 따라서 toString을 호출하면 생성 한 Foo 개체의 toString이 호출됩니다.

BirdEaglefly의 배열 목록이 아름답게 있다고 가정 해 보겠습니다. 따라서 실제로 EagleBird이라는 fly() 메서드를 호출하면 아름답게 비행합니다. 이것은 사실상 상속의 위대한 특징이며 매우 합리적입니다.

1

진실은 JVM이 어떻게 원래대로 되돌려 놓을 지 모른다는 것입니다. 우리는 그 일을해야 할 것입니다. 이것을 고려하십시오 ... (코드 줄 이후)

SomeOtherObject obj = arr.get(2); //trying to access the third element 

확실히 컴파일 타임 오류가 발생합니다. 이제는 반환 된 객체를 명시 적으로 캐스팅하려고합니다.

SomeOtherObject obj = (SomeOtherObject)arr.get(2); 

완벽하게 정상적으로 작동합니다. 왜? get() 메서드에서 반환 된 객체가 캐스팅 된 유형과 호환 가능하기 때문입니다.

이제 JVM이 어떤 객체인지 알 수 있는지 확인하기 위해서도 이것을 고려해보십시오.

SomeOtherObject obj = (SomeOtherObject)arr.get(1); //1 instead of 2 

예이 배열의 두 번째 멤버가 String이며이를 수행 할 수 없다는 것을 알고 있습니다. 그러나 JVM이 무엇을 말해야하는지 알 수 있습니다 (컴파일러 오류는 없습니다). 우리가 얻는 메시지는 객체가 지정된 유형으로 형변환 될 수 없다는 것입니다. (하지만 우리는 객체의 정확한 유형을 얻지 못합니다).

요점을 얻었습니까? 여기서 JVM은이 배열에 전달되는 객체가 Object와 호환되는 객체라는 것을 알고 있습니다. String, int (또는 Primitive가 콜렉션에 저장 될 수 없기 때문에 Integer), SomeOtherObject (Java에서 정의 된 모든 클래스는 Object의 직접적인 서브 클래스)를 실제로 전달했는지는 알 수 없습니다.

지금 당신의 질문에 대답 :

  1. (어떻게 나는 내가 할 수 다시 정상으로 (나는 아직도 할 것이다 있지만 직접 입력 캐스트) 문자열과 정수를 얻기 위해) 해당 문자열 인 이유와 래퍼 클래스 (Integer는 래퍼 클래스 임)는 Object에서 상속 된 toString() 메서드를 재정의했습니다. 따라서 이러한 객체를 인쇄하면 실제 값을 얻을 수 있습니다.

  2. (JVM이 어떤 유형으로 변환 할지를 어떻게 알 수 있습니까?) JVM은 사용자에게 반환하기 전에 어떤 유형으로 변환 할 객체가 실제로 들어 있는지 알지 못합니다. Object의 인스턴스 만 반환합니다 (JVM이 모두 객체에 대해 알고있는 것입니다). 명시 적으로 적절한 유형으로 변환해야합니다.

희망 사항 귀하의 질문에 답변했습니다. 그게 확실하지 않으면 알려줘. 런타임 다형성 (제목 질문)에 대한

자세한 설명은이 사이트에서 제공됩니다 : http://www.javatpoint.com/runtime-polymorphism-in-java