2012-11-21 4 views
3

평범한 캐스트 (기본적으로 실제로는 문제가되지 않는 잠재적으로 안전하지 않은 여러 뭉치를 감싼 래퍼)를 수행 할 라이브러리가 있는지 궁금합니다. 예를 들어, (간결함을 위해 생략 몸) 라이브러리에 다음과 같은 I가 있다고 가정합니다..자바 주조 유틸리티 라이브러리

public interface LibraryInterface; 

public static void doSomething(Collection<LibraryInterface> collection); 

그래서 doSomething() 고집 만 가능합니다 것보다 덜 유연 뭔가를한다 (즉, Collection<? extends LibraryInterface>는 기능을 제공하는 라이브러리가 있나요 ?

내가 LibraryInterface를 구현하는 클래스를 가지고 있고, 나는 List<MyLibraryInterfaceImpl>이있는 경우, 나는 아직도 그 목록을 주조로 doSomething()을 사용할 수 있도록
public static <T, U extends T> Collection<T> cast(Collection<U> collection); 

(cast()의 본문이 포함 암시 : 다음과 같은 맥락에서 안전하지 않은 캐스트지만 적어도 캐스트가 숨겨져 있거나 한 곳에서 중앙 집중화 된 사용자의 입장).

(비교기와 같은 뭔가 반대를 않습니다 또한 좋은, 일)

답변

1

는 이러한 라이브러리가 아닌 의미 일 것이다. 형식 지우기 때문에 부모 클래스로 캐스팅하는 것은 컴파일러 경고를 제거하는 것을 제외하고는 전혀 수행하지 않습니다. 또한 도서관이 직접 할 것은 컬렉션을 직접하거나 캐스트를 복사하는 것입니다. 다시 말하면, 당신이하고 싶지 않았던 일을 정확히 수행했기 때문에이 라이브러리를 사용하도록 동기를 부여했거나, 실제로는 비효율적이고 쓸모없는 것입니다 ...

다운 캐스팅은 내용을 확인하려는 경우 훨씬 더 의미가 있습니다. 안전하지 않은 캐스트를하기 전에 컬렉션의 컬렉션을 반복하여 모든 요소의 유형을 확인한 다음 안전하지 않은 캐스트를 수행하여 컬렉션을 반환하는 함수를 만들 수 있습니다. ~ 3 줄에이 함수를 작성할 수 있습니다;). 당신의 cast(Collection<U> collection) 방법은 <T extends LibraryInterface> doSomething(Collection<T> collection)

라이브러리의 추가 점은 무엇인가에 의해 달성 될 수있다 않습니다

1

다?

또한 API 빌더가 유형을 변경하지 않기로 결정한 경우 이는 기본적으로 계약을 준수하고 LibraryInterface만을 제공하거나 특정 용도로만 사용하기를 원합니다. 또한 자바 제네릭 이 type erasure

List<? extends Object> p = new ArrayList<Object>(); 

하지만 지금 List<? extends Object> p = new ArrayList<? extends Object>(); 위의 불법 할 수 있습니다. 그래서 typecasting과 루핑을하지 않고 먼저, 그런 라이브러리를 구현하는 다른 방법을 모른다. 그것은 당신이 무엇을 적 목적을 위해 원하는대로 가능했던 것

List<Object> p = new ArrayList<String>();

그래서 당신이 원하는 무엇을, 제네릭하고 공동 변형을했다 위해, 즉. 그러나 위의 진술은 불법입니다. 그러므로 당신은 그것을 생략 할 수 없습니다.

그래서 위의 작업을 수행하는 유일한 방법은 루프를 검사하고 궁극적으로 캐스팅을 입력하는 것입니다.

더 많은 정보는 here 지금

1

here, 이러한 라이브러리가 무엇을 할 것를 찾을 수 있습니까?

void flexibleDoSomething(Collection<? extends LibraryInterface> collection) { 
    doSomething((Collection<LibraryInterface>) collection); 
} 

이 방법은 라이브러리 가치가없는 것처럼 보입니다. 이렇게하면 여분의 유형 안전을 얻지 못합니다. 분명히 훨씬 좋은 점은 처음에 다른 라이브러리를 수정하는 것입니다. 그러나 당신은 항상 방법을 인라인 할 수 있습니다.

이러한 라이브러리를 사용하는 경우가 있습니다. 주로 캐스트가 하나의 클래스에 집중되도록하기 위해 자주 사용하거나 구문 적으로 지저분한 경우가 있습니다. 예 : 복잡한 제네릭의 경우 Class<Foo<?>> ~ Class<Foo<Something>>을 캐스팅합니다.

제네릭을 사용하는 경우 모든 유형이 컴파일러에 올바르게 바인딩되도록 오른쪽에 나타나야합니다.

public static <T, U extends T> Collection<T> cast(Collection<U> collection); 

이 방법은 컴파일러 행복하게 TObject 있다고 가정합니다.

엄격한 제네릭을 얻으려면, 당신은, 당신이 실제로 T, 그리고 (물론,하지 Collection에 대한하지만, 다른 상황)를 지정할 수 있습니다

public static <T, U extends T> Collection<T> cast(Collection<U> collection, Class<T> clz); 

이 방법 같은 것을 사용 할 수 있습니다, 유틸리티 방법은 수 또한 형식 검사를 수행하십시오.