[java] List <Object>를 List <MyClass>로 캐스팅하는 방법

이것은 컴파일되지 않으며 어떤 제안이라도 감사합니다.

 ...
  List<Object> list = getList();
  return (List<Customer>) list;

컴파일러는 말한다 : 캐스팅 할 수 없습니다 List<Object>List<Customer>



답변

먼저 Object로 업 캐스팅하여 모든 객체를 모든 유형으로 캐스팅 할 수 있습니다. 귀하의 경우 :

(List<Customer>)(Object)list; 

런타임시 목록에 Customer 개체 만 포함되어 있는지 확인해야합니다.

비평가들은 이러한 캐스팅이 코드에 문제가 있음을 나타냅니다. 이를 방지하기 위해 유형 선언을 조정할 수 있어야합니다. 그러나 Java 제네릭은 너무 복잡하고 완벽하지 않습니다. 런타임 유형을 잘 알고 있고 수행하려는 작업이 안전하다는 것을 알고 있더라도 컴파일러를 만족시킬 수있는 예쁜 솔루션이 있는지 알 수없는 경우가 있습니다. 이 경우 필요에 따라 원유 주조를하여 집에 직장을 떠날 수 있습니다.


답변

고객 객체 이지만 고객 목록은 객체 목록 이 아니기 때문 입니다. 그것이 경우에, 당신은 넣을 수 있는 고객의 목록에서 개체를.


답변

다른 코드에 따라 가장 좋은 답변이 다를 수 있습니다. 시험:

List<? extends Object> list = getList();
return (List<Customer>) list;

또는

List list = getList();
return (List<Customer>) list;

그러나 이러한 확인되지 않은 캐스트를 수행하는 것은 권장되지 않습니다.


답변

Java 8 Streams 사용 :

때때로 무차별 대입 캐스팅이 괜찮습니다.

List<MyClass> mythings = (List<MyClass>) (Object) objects

그러나 여기에 더 다양한 솔루션이 있습니다.

List<Object> objects = Arrays.asList("String1", "String2");

List<String> strings = objects.stream()
                       .map(element->(String) element)
                       .collect(Collectors.toList());

많은 이점이 있지만 목록에 포함 된 내용이 확실하지 않은 경우 목록을보다 우아하게 캐스팅 할 수 있습니다.

objects.stream()
    .filter(element->element instanceof String)
    .map(element->(String)element)
    .collect(Collectors.toList());


답변

이중 캐스트를 사용할 수 있습니다.

return (List<Customer>) (List) getList();


답변

저는 자바 프로그래머가 아니지만 .NET 및 C #에서는이 기능을 반 변성 또는 공분산이라고합니다. 나는 아직 베타 버전이기 때문에 사용하지 않는 .NET 4.0의 새로운 기능이므로 두 용어 중 어떤 것이 문제를 설명하는지 모르겠지만 설명하겠습니다. 기술적 인 문제입니다.

캐스팅이 허용되었다고 가정 해 봅시다. 내가 말한 것이므로 cast 라고 말하지만 가능할 수있는 두 가지 작업, 캐스팅변환 .

변환은 새로운 목록 객체를 얻는 것을 의미하지만 캐스팅이라고 말하면 한 객체를 일시적으로 다른 유형으로 취급하고 싶습니다.

여기에 문제가 있습니다.

다음이 허용되면 어떻게 될까요? (참고, 캐스트 전에 개체 목록에는 실제로 Customer 개체 만 포함되어 있다고 가정합니다. 그렇지 않으면이 가상 버전의 Java에서도 캐스트가 작동하지 않습니다.)

List<Object> list = getList();
List<Customer> customers = (List<Customer>)list;
list.Insert(0, new someOtherObjectNotACustomer());
Customer c = customers[0];

이 경우 고객이 아닌 개체를 고객으로 처리하려고 시도하고 목록 내부의 양식이나 할당에서 한 지점에서 런타임 오류가 발생합니다.

그러나 Generics는 컬렉션과 같은 유형 안전 데이터 유형을 제공해야하며 ‘보장’이라는 단어를 던지기를 좋아하기 때문에 뒤 따르는 문제가있는 이러한 유형의 캐스트는 허용되지 않습니다.

.NET 4.0 (당신의 질문은 자바에 관한 것이 었습니다)에서 이것은 매우 특정한 경우에 허용 됩니다 컴파일러가 당신이하는 작업이 안전하다는 것을 보장 할 수있는 . 그러나 일반적으로 이러한 유형의 캐스트는 그렇지 않습니다. 허용됩니다. Java 언어에 공 변성 및 반 변성을 도입 할 계획이 있는지 확실하지 않지만 Java도 마찬가지입니다.

나보다 더 나은 자바 지식을 가진 사람이 자바 미래 또는 구현에 대한 세부 사항을 알려줄 수 있기를 바랍니다.


답변

또 다른 접근 방식은 Java 8 스트림을 사용하는 것입니다.

    List<Customer> customer = myObjects.stream()
                                  .filter(Customer.class::isInstance)
                                  .map(Customer.class::cast)
                                  .collect(toList());