2013-02-25 3 views
7

UnaryFunction 인터페이스가 으로 정의되어 있다고 가정합니다. Effective Java generics 장.이 검사되지 않은 경고를 억제하는 것이 안전합니까?

public interface UnaryFunction<T> { 
T apply(T arg); 
} 

하고 왜 (UnaryFunction<T>)IDENTITY_FUNCTION의 캐스트가 안전하게 UnaryFunction

// Generic singleton factory pattern 
private static UnaryFunction<Object> IDENTITY_FUNCTION = new UnaryFunction<Object>() { 
    public Object apply(Object arg) { return arg; } 
}; 

// IDENTITY_FUNCTION is stateless and its type parameter is 
// unbounded so it's safe to share one instance across all types. 
@SuppressWarnings("unchecked") 
public static <T> UnaryFunction<T> identityFunction() { 
    return (UnaryFunction<T>) IDENTITY_FUNCTION; 
} 

을 반환하는 다음 코드?

이 책에서는 내가 묻는 질문에 대해 이렇게 말했지만, 여기서 논리를 따를 수는 없다. 신원 작업을 수행하는 apply 함수를 어디에서 호출할까요? 나는 아무것도 수정하지 않고 동일한 객체를 전달하는 함수이기 때문에 혼란 스럽다. UnaryFunction<Object> 모든 T에 대한 UnaryFunction<T> 아니므로

(UnaryFunction<T>)에 IDENTITY_FUNCTION의 캐스팅은 되지 않은 캐스트 경고를 생성합니다. 이 인수가 수정되지 않은 반환, 그래서 우리는 형태 보증은 T의 무엇이든 값이 UnaryFunction<T>으로 에게 그것을 사용하는 것을 알고 :하지만 신원 기능은 특별하다. 따라서 은이 캐스트를 에 의해 생성 된 검사되지 않은 캐스트 경고를 자신있게 표시하지 않을 수 있습니다. 이 작업을 완료하면 오류없이 코드가 컴파일되거나 경고가 표시됩니다. 타입 삭제

T apply(T arg); 

+0

사이드 질문 : 어떤 책을 사용하고 있으며이 코드의 요점은 무엇입니까? – asteri

+0

@Jeff Effective java는 책 이름이며 generic 함수를 설명하는 절에서 제네릭 장에 있습니다. – Geek

답변

3

캐스팅 신원 기능은 처음에 자신에게 전달 된 정확한 객체를 반환 전용으로 지라 안전합니다. 따라서 실행시 캐스트를 위반할 수있는 일반 매개 변수 T의 특수화가 없습니다.

아카, 객체를 자체 유형으로 캐스팅합니다.

3

실제로는 항상 올바른 (y = x;에 해당합니다)을 전제 정체성

Abc x = ...; 
Abc y = IDENTITY.apply(x); 

하나 지금

Object apply(Object arg); 

입니다.

(매우 실용적.)

+0

해당 코드에서 'apply'는 어디에서 호출 되었습니까? – Geek

+0

identityFunction이 적용될 때마다 (결과 : T IDENTITY.apply (T)) 일반적으로 수행 할 수없는 매개 변수의 T는 런타임에 없기 때문에 결과가 할당됩니다. –

1

identityFunction()은 단순히 다른 객체에서 사용할 함수 자체를 반환합니다.

String result = identityFunction().apply("Hello"); 

유형의 안전 경고 중요 : 다음

사용법 예이다. IDENTITY_FUNCTION이 구현되어 컴파일러가 함수가 입력과 동일한 유형을 반환하도록 보장 할 수 없기 때문입니다. 다음 대체 구현을 고려

private static UnaryFunction<Object> CONST_FUNCTION = new UnaryFunction<Object>() { 
    public Object apply(Object arg) { return "Default"; } 
}; 

이 구현은 항상 문자열을 반환, 그래서 일반 데이터 유형에 대한 단항 함수로 돌아 분명 안전하지.

이 경우 (IDENTITY_FUNCTION), 반환 된 유형이 입력 유형과 동일하다는 증거는 구현 내부에 있습니다. 우리는 동일한 인스턴스를 리턴하므로 동일한 타입을 가질 수 있습니다. 형식 안전 경고를 표시하지 않을 경우이를 증명할 것을 권장합니다.

+0

-1 혼란스러운. IdentityFunction()은 "함수 자체"를 반환하지 않고 _argument_ 자체를 반환합니다. T 형의 결과가 "다른 객체에 사용되는"이유는 없습니다. 귀하의 예제에서 그것은 다른 개체에서 _ _ 사용할 수없는 _ 문자열입니다. – user949300

+1

@ user949300 :'identityFunction()'은 변수'IDENTITY_FUNCTION'에 저장된 객체에 대한 참조를 반환합니다. 그 참조는 당신이'apply()'를 호출 할 수있게 해주므로'identityFunction()'는 함수 자체를 효과적으로 반환합니다. 이름이 같지 않은 것이 더 좋았을 것입니다. Ex'getIdentityFunction()'과'IDENTITY_FUNCTION'입니다. 대답의 첫 번째 줄은 getter 메서드를 참조합니다. – unholysampler

+0

감사합니다. 이 전체 질문/시스템은 아무것도하지 않는 것을 혼란스럽게합니다 :-). StackOverflow의 한계로 인해 답변을 편집 할 때까지는 내 downvote를 "실행 취소"할 수 없습니다. – user949300

관련 문제