2013-05-25 3 views
1

저는 석영 작업 내에서 스프링 데이터 저장소의 인스턴스를 얻으려고 import org.springframework.data.repository.support.Repositories을 사용하고 있습니다.캐스트에서 중간 단계 제거

Repositories 클래스 그러나 저장소 CrudRepository<Object, Serialiazable>로 입력되는 각각의 저장소의 인스턴스를 리턴하는 방법 getRepositoryFor(Class<?> domainClass)있다.

반환 된 CrudRepository을 사용자 지정 리포지토리 유형 CustomerRepository으로 업 캐스팅하려고하면 Eclipse에서 캐스팅을 수행 할 수 없다는 메시지를 표시합니다. I 유형 CrudRepository<Customer, Long> repository의 필드에 저장소를 할당하는 경우

// Eclipse Error: Cannot cast from CrudRepository<Object,Serializable> 
    // to CustomerRepository 
    this.customerRepository = 
     (CustomerRepository)super.repositories.getRepositoryFor(Customer.class); 

그러나, 나는 다음 CustomerRepository에 깁스를 할 수 있습니다.

//No Problems here 
CrudRepository<Customer, Long> repository = 
    super.repositories.getRepositoryFor(Customer.class); 
CustomerRepository repository = (CustomerRepository) repository; 
  1. 는 이 캐스트를 수행하는 데 필요한이 중간 단계를 피하기 위해 anway이 있습니까?

  2. 첫 번째 캐스트에서 어떤 문제가 발생합니까?

답변

2

문제가있어서 정의 "getRepositoryFor"이다. 정의 된 제네릭을 사용하여 변수에 지정하지 않으면 "T"제네릭에 대한 계약을 설정하지 않습니다.

public <T,S extends Serializable> CrudRepository<T,S> getRepositoryFor(Class<?> domainClass) 

나는 컴파일러, 그 수준에서, CustomerRepositoryCrudRepository<Customer, Long>를 확장 것을 볼 수 없습니다 같아요.

public class TestCast { 

    public static class MyMap extends HashMap<String, String> { 
    } 

    public static <T> Map<T,String> getMap1(Class<?> myClass) { 
     return new HashMap<T,String>(); 
    } 

    public static <T> Map<T,String> getMap2(Class<T> myClass) { 
     return new HashMap<T,String>(); 
    } 

    public static void main(String[] args) { 

     // Works, because it knows T is String as you state it with the variable type Map<STRING,String> 
     Map<String,String> map = getMap(String.class); 

     // Compilation error, it doesn't know T is String and cast won't work either 
     MyMap myMap = getMap1(String.class); 

     // Works, because it knows T is String as it is getting it in the method parameter, no need to rely on the variable that is getting the value 
     MyMap myMap = (MyMap) getMap2(String.class); 
    } 

} 

이 자바에서 복잡한 영역이고 컴파일러의 복잡성을 줄일 수있는 몇 가지 알려진 제한 사항이 있습니다 :이 예제에서는 문제를 이해하는 데 도움이 될 것입니다 생각합니다.

+0

그래서, 무엇을 변경 또는 제네릭 형식 매개 변수가 알려진 것을 발생 : 자바 8에서

는, 타입 추론이 더 상황에 맞는 유형 정보를 활용, 당신의 코드는 작동 할 수있다? 첫 번째 과제를 수행 할 때 당신이 아직 정의되지 않은 클래스의 객체를 할당하기 때문에 –

+0

, 그것은'CrudRepository가에', S'가'Long'입니다'T'는'Customer'이다 '것을 알고 알려진 클래스'CrudRepository '의 변수. 그런 다음 평소와 같이 업 캐스팅 할 수 있습니다. 그러나 첫 번째 과제를 건너 뛰면 'CustomerRepository'의 'T'가 고객임을 알 수 없으므로 'T'를 '객체'로 간주합니다. S와 Long에 대해서도 마찬가지입니다. 그런 다음 붙여 넣은 오류가 있습니다 : 좋아 CustomerRepository – MaQy

+0

에 <직렬화, 개체> CrudRepository에서 캐스팅 할 수 없습니다, 또 하나의 문제는 그렇게 할당시'Customer'에 그것을 업 캐스팅'T'합니까? 형식 매개 변수가 호환되는지 어떻게 알 수 있습니까? 나는 그것의 더 나은 것 같아요 유형으로 할당 된 유형이 필드에 의해 지정된 유형인지 알고 말했지? –

0

이것은 유형 유추에 관한 것입니다. 여기 T을 추론 할 수있는 충분한 정보가없는 우리가 메소드 선언

<T> T foo(){ return null; } 

foo(); 

같은 문을 말해봐.

void bar(String str){ } 

bar(foo()); // T must be String, right? 
일반적으로

이 지원되지 않는 것처럼, 추론을 지원하기 위해 사용 컨텍스트 정보를 컴파일러 수 없습니다; 당신은 그것이 일반적으로 얻을 수있는 복잡함을 상상할 수 있습니다.

그러나 두 특정한 경우에, 타겟 타입은 Java5 Java7에서 진실 인 타입 추론

String s = foo(); // assign it to a type 

String baz() 
{ 
    return foo(); // return it to a type 
} 

에서 고려된다.나는이 임무를 수행 할 때

관련 문제