그래서 인터페이스가 SuperType
이고 클래스를 구현하는 경우 TypeA
, TypeB
등이 있습니다. GeneralProduct
를 구현 내가 공장을 가지고 캐스트하지 않고도 제네릭 인터페이스를 구현하는 특정 클래스의 팩토리를 얻으려면 어떻게해야합니까?
public interface UsedByProductThing<T extends SuperType> {
public T doStuff(T one);
}
(아래 참조) 생산 제품 : : 여기
public interface GeneralProduct<T extends SuperType> {
T doSomething(T input);
}
ProductA
구현된다
public class ProductA implements GeneralProduct<TypeA> {
UsedByProductThing<TypeA> in;
public ProductA(UsedByProductThing<TypeA> in) {
this.in = in;
in.doStuff(new TypeA());
}
@Override
public TypeA doSomething(TypeA input) {
return null;
}
}
이제 문제의 공장 :
public class GeneralFactory {
public static <T extends SuperType> GeneralProduct<T> createProduct(
int type, UsedByProductThing<T> in) {
switch (type) {
case 1:
return (GeneralProduct<T>) new ProductA((UsedByProductThing<TypeA>) in);
// at this point, i want to return a "new ProductA(in)" preferably
// without casting
// or at least without the cast of the argument.
default:
throw new IllegalArgumentException("type unkown.");
}
}
}
주석으로, 나는 factory-method가 캐스트를 사용하지 않기를 바란다. 반환 유형이 GeneralProduct 여야한다는 것을 알고 있지만 캐스트를 생략하는 방법을 생각할 수 없습니다 (그리고 이는 나에게 "확인되지 않은 캐스트"- 경고도 함). 또한, 나는 논쟁의 캐스트를 생략하는 방법을 생각할 수 없다. 그 장소에서 "안전하지 않은"캐스팅을 제거해야하는 경우 전체 코드를 재구성 할 수 있습니다. 여기에 친절하고 매끄러운 방법을 말해 줄 수 있어요?
또한 원하는대로 질문을 편집하십시오. 제목에서 문제를 올바르게 해결하는 방법을 모르겠습니다.
고마워요!
왜 반환 유형의 캐스트를 없애고 싶지는 모르겠지만 괜찮습니다. 안전하지 않은 매개 변수에 대해서는 사용자가'type'에'1'을 전달하면 항상'UsedByProductThing'을 전달한다는 가정을하기 때문입니다. 사용하는 코드가 항상이 계약을 만족한다는 것을 아는 경우라면 괜찮습니다. 그렇지 않으면 문제가 있습니다. –
한 가지 기억해야 할 점은 type-erasure로 인해 모든 제네릭 형식이 런타임에'Object'로 변환된다는 것입니다. 따라서'UsedByProductThing'은'UsedByProduceThing
유형 삭제에 대해 알고 있습니다. 제네릭이 있기 전에는 Java를 사용하지 않았기 때문에 그러한 유형의 (형용사) 유형 캐스팅이 실제로 필요한 지점에 도달하지 못했습니다. 또한'((UsedByProductThing) in '과 같은 캐스트가 왜'in' 유형이'(UsedByProductThing )'입니까? 내가 올바르게 이해했다면, 타입 지우기 전에 컴파일러를위한 것이고 그 후에는 완전히 생략됩니다 - 맞습니까? –
Mitja