Java 바이트 코드는 강력하게 유형이 지정되고 검증됩니다. 이는 호출자의 코드가 호출 된 메소드가 반환 할 코드와 호환 가능해야 함을 의미합니다. 따라서 호출자의 메서드 참조에 예상되는 반환 형식이 포함되지 않은 경우에도 코드에 여전히 암시 적 가정이 포함되어있었습니다 (예 : 결과와 함께 long
연산을 시도하면 메서드가 Object
또는 void
이 아닌 long
을 반환 할 것으로 예상됩니다.
예상되는 반환 형식을 나타내는 메서드 참조를 사용하면 확인 작업이 간단 해지고 전체 프로세스를보다 효율적으로 처리 할 수 있습니다. 실제 연결을 수행하지 않고 예상되는 메서드 서명을 사용하여 메서드 코드의 정확성을 확인할 수 있습니다. 메소드 호출 명령어가 최종적으로 링크되면 실행 가능 코드를 확인할 필요가 없으며 서명 만 일치해야합니다.
그래서 자바 소스 코드가 최소한 이전 버전에서는 다른 리턴 유형을 정의 할 수 없더라도 자바 바이트 코드가 그렇게 설계되었습니다. Java 5부터는 규칙이 더 이상 엄격하지 않습니다.
다음 인터페이스 고려해
interface StringFunction<R> {
R apply(String input);
}
인해 타입을 소거하는, 상기 바이트 코드 레벨에있어서 Object apply(String input)
있을 것이다.
지금 다음 구현 클래스 고려 :
class Length implements StringFunction<Integer> {
public Integer apply(String input) {
return input.length();
}
}
뿐만 아니라보다 구체적인 반환 형식이 허용 선언되고, 그것은 실제로 일반 타입 시스템에 따라 같은 자바 언어로 필요한입니다, 그것은 상속 추상 방법 Integer apply(String)
에서 StringFunction<Integer>
. 바이트 코드 레벨
, 그것은 실제 구현 방법
Integer apply(String)
뿐만 아니라 정식 바이트 코드 레벨에서
interface
계약을 만족하고, 실제 구현 방법에 위임
다리 방법
Object apply(String input)
있을 것이다.제네릭 효과적으로 반환 형식의 축소를 할 수 있기 때문에
이 아닌 일반 메소드를 거부 할 이유가 없었다, 따라서, 자바는 소위 허용 공변 반환 형식뿐만 아니라 자바 5 가입일 :
class Base {
Object getValue() {
return null;
}
}
class Sub extends Base {
@Override String getValue() {
return "now a string";
}
}
그래서 오버로드가 아닌 동일한 매개 변수 유형이지만 다른 리턴 유형의 여러 메소드를 갖는 클래스를 생성 할 수 있습니다.
이러한 경우는 대안으로 처리 될 수 있습니다. 메소드가 매개 변수 유형으로 만 구별되고 리턴 유형은 동일하거나 더 구체적이어야하며 공변 리턴 유형과 호환 가능해야한다는 것을 정의함으로써 메소드 테이블을 빌드 할 때 JVM이 모든 리턴 유형을 열심히 해결해야한다는 것을 암시합니다 클래스의 유형이 실제로 더 구체적인 지 여부를 확인합니다. 그리고 호출자와 호출 수신자간에 적절한 계약을 맺기 위해서는 반환 형식을 인코딩해야합니다.
반환 유형이 변경되면 오류가 발생하지 않아야합니까? 라이브러리의 메소드 결과를 할당하지만 이후에 라이브러리가 변경되어 void 또는 호환되지 않는 객체를 반환하는 경우 어떻게해야합니까? –