2010-03-19 3 views
12

각 명령문에 대해 a에서 검색 한 요소를 명령문 자체에 캐스팅하는 것이 가능합니까 (아니면 권장 할 만합니까)? 목록의 각 요소는 <SubType>입니다.Java의 캐스트 요소

즉 :

List<BaseType> list = DAO.getList(); 
for(<SubType> element : list){ 
    // Cannot convert from element type <BaseType> to <SubType> 
    ... 
} 

보다는 :

List <BaseType> list = DAO.getList(); 
for(<BaseType> el : list){ 
    <SubType> element = (<SubType>)el; 
    ... 
} 

답변

12

당신이 정말 각 항목이 하위 유형이 될 것입니다 것을 알고 계십니까? DAO는 단순히 List<BaseType> 계약을 수행해야하며, 서브 클래스를 가정한다면 어딘가에 문제가 있다고 생각합니다. 아마도 DAO에 대한 인터페이스를 올바로 가져 오는 데 더 집중하고 계약 상 원하는대로 반환해야합니다.

+0

+1 인터페이스가 준수해야하는 계약 메커니즘을 너무 자세히 설명합니다. – aperkins

+1

불행히도 DAO 코드는 우리가 아닙니다. 그러나 데이터 소스로의 피드는 다음과 같습니다. 우리는 클래스에 추가 기능을 원했기 때문에 (유일한 하위 클래스)을 하위 클래스로 만들었습니다. 우리가 입력을 제어하고 우리는 단지 객체를 거기에 넣었 기 때문에 검색된 객체가 실제로 중 하나가 될 것이라고 확신 할 수 있다고 느낍니다. 우리가 모든 코드를 관리한다면 100 % 정확할 것입니다. –

+3

@Carl - 그러면 DAO를 래핑하고 원하는 것을 수행하는 * 다른 * 인터페이스를 제공하는 것이 좋습니다. 그렇지 않으면 코드베이스 전체를 변환해야합니다 (잠재적으로 - 이것이 얼마나 광범위하게 분포되어 있는지에 대한 가정을하고 있습니다). –

1

가능합니다. 하지만 신이 금지 한 이유는 무엇입니까? 내 경력에 대한 나의 초기 시도가 그랬고 나는 배웠다. 인터페이스 프로그래밍은 항상 장점이 ​​있습니다. 중급 개발자 만이 하위 유형에만 필요한 메소드/기능이있는 케이스를 처리하는 것에 대해 질문을 받는다.

말 bark() 메서드가있는 Dog 하위 유형이있는 동물 클래스입니다. 그들은 bark() 기능을 원합니다. 실제적인 도전은 그들이 껍질을 벗기지 않고 동물을 말하게하는() 동물 커뮤니케이션의 행동을 원한다는 것입니다. 따라서 새 Cat 하위 클래스에는 meow()가 필요하지 않습니다. 다음은 이것에 관한 것입니다 : - 나의 강아지의 형태는 한 팩이지만 고양이는 그렇지 않습니다. 답변 팩() 동작은 단일 개가 소유하지 않습니다. 팩은 다른 측면이며, 모든 오브젝트에 팩을 전달하고 오브젝트에 팩에 참여하도록 요청합니다. (방문자 패턴/어댑터 패턴). My Wolf 클래스도 같은 동작을 사용할 수 있습니다.

나는 이것에 대해 엄격하다. 대답이 확실하지 않다면 인터페이스 계약을 통해보다 안전하게 게임을 즐기십시오.

12

다른 사람들이 언급 한 모든 이유 때문에이 작업을해서는 안됩니다. 당신이 인터페이스를 변경할 수없는 경우, 다음이 가능합니다 :

for (BaseType element : list) { 
    SubType subType = (SubType)element; 
    ... 
} 

지금까지 내가 아는 한,이이 작업을 수행 할 수있는 유일한 방법은 진정으로 안전 입력 상태로 유지 - 하나를 잡으려고 유형의 삭제에 의존하지하여 예 문제는 훨씬 늦어 질 때까지는 반드시 필요하지는 않습니다.

나는 이것이 당신이 찾고 있던 것이 아니라는 것을 알고 있습니다. 그러나 그것은 캐스팅을 다루고 있습니다.

+0

인터페이스를 변경할 수 있고 항상 SubType이된다면 하위 클래스 확장을 사용하든 아니면 변경 만하든간에 인터페이스를 변경해야한다는 것에주의해야합니다. – aperkins

+2

정말 안전하기 때문에 다음과 같이 할 수 있습니다 : if (element instanceof SubType) – VolatileDream

+0

매우 사실입니다. – aperkins

0

Google 소식 모음의 일부가 아닌 경우 transform 방법으로 목록을 감쌀 수 있습니다. 귀하의 경우 그것은 매우 효율적이며 완전히 준수 할 것입니다. 나는 Brian이 제안한 것처럼 래퍼 메소드로 그것을 넣을 것이다.

public List<SubType> fromDao () 
{ 
    // Put a comment for maintainer 

    // Lists from DAO always contain SubTypes 
    return 
     Lists.transform(
      DAO.getList(), 
      new Function< BaseType, SubType >() 
      { 
       public SubType apply (final BaseType from) 
       { 
        return (SybType) from; 
       } 
      }; 
} 
9

과 같이, for 루프로 캐스트를 결합하는 사실 수 있습니다 :

List<BaseType> list = DAO.getList(); 
for (SubType subType : ((List<SubType>) list)){ 
    ... 
} 

을 또는 당신이 약간 클리너 패턴을 사용할 수 있습니다

List<SubType> list = (List<SubType>) DAO.getList(); 
for (SubType subType : list){ 
    ... 
} 

당신의 뜻을 Java 컴파일러에서 억제되지 않은 캐스트 경고를받습니다. 첫 번째 형식의 효과는 루프 내의 각 요소를 형 변환하는 것과 실질적으로 동일합니다. 두 번째 양식은 목록에 새롭게 추가 된 내용이 SubType에 부합해야한다는 것을 강요합니다.

배열에는 고유 한 런타임 유형이 있으므로 배열과 함께 작동하지 않습니다. 즉, BaseType []은 SubType []에 캐스팅 할 수 없습니다. 배열 API를 사용하면 다음과 같이이 문제를 해결할 수 있습니다.

BaseType[] array = DAO.getArray(); 
for (SubType subType : Arrays.<SubType>asList(array)) { 
    ... 
} 
+0

[몇 가지 트릭]을 할 수 있지만 그 캐스트는 합법적이지 않습니다 (https://stackoverflow.com/questions/933447/how-do-you-cast-a-list-of-objects-from-one-type- to-another-in-java)를 사용하여 (예 : ''에 대한 중간 캐스트). [java tutorial] (https://docs.oracle.com/javase/tutorial/java/generics/subtyping. html)은 "Integer가 Number의 하위 유형이지만 List 은 List 의 하위 유형이 아니며 실제로이 두 유형은 관련이 없습니다. List 및 List 의 공통 상위 항목은 List 입니다. . " –

+0

두 번째 예제는 DAO.getList가 List 이 아닌 형식화되지 않은 List를 반환하는 경우에 작동합니다. 이 패턴은 콜렉션이 입력되지 않은 레거시 코드베이스를 다룰 때 유용 할 수 있습니다. – harperska