2017-02-18 12 views
2

こんにちは、私はコントローラの基本メソッドとして汎用メソッドを実装しようとしていますが、generericメソッドのsygnatureで私が理解できない問題が発生します。一般的なメソッド、等価制約

Incompatible equality constraint: T and capture of ? extends Object 

答えて

3

問題が発生する場所は正確には言いませんが、body.getClass()をパラメータとして渡した結果、restTemplate.exchange(コールで発生すると思います。 body.getClass()の戻り値の型がClass<? extends Object>あるので、これは、as in the Javadocです:

実際の結果型が|X|getClass

問題と呼ばれる上式の静的タイプの消去ですClass<? extends |X|>ですbodyが具体的にはTであることを保証できないことです。Tのサブクラスになる可能性があります。したがって、body.getClass()の結果はClass<T>ではない可能性があります。

タイプセーフでなければならない場合は、そのメソッドに追加のパラメータとして渡す必要があります。 Class<T>を得るための唯一の方法は、例えば、クラスリテラルを使用することであること

<T> ResponseEntity<T> makeApiCall(
    String path, HttpMethod httpMethod, T body, Class<T> bodyClass, 
    boolean isAdmin){ 
    // ... 
    ResponseEntity<T> responseEntity = 
     restTemplate.exchange(
      path, HttpMethod.POST, entity, bodyClass); 
    // ... 
} 

String.classの場合、TStringです。これは、ジェネリックなクラスリテラルがないため、ジェネリックボディタイプの使用を排除します。

+0

"クラスを取得する唯一の方法は、Tが文字列の場合はString.classなどのクラスリテラルを使用することです。これはジェネリッククラスリテラルが存在しないため「ジェネリックボディタイプの使用を排除します。とにかく、コンパイル時にコンパイラはジェネリック型を見つけ出すことができます。 'getClass()'の結果を 'Class '変数に代入するのはどうですか? –

+1

@LewBloch:私は彼が意味することは、 'T'はreifiable型でなければならないということです。そうでない場合、 'T'が' Foo 'のようなパラメータ化された型であるとすれば、実際には安全ではない' Class 'を提供する必要があります。 – newacct

1

は、あなたがそれをタイプセーフにするためにClass<T>

@SuppressWarnings("unchecked") 
<T> ResponseEntity<T> makeApiCall(String path, HttpMethod httpMethod, T body, boolean isAdmin){ 

    String sender = isAdmin ? adminHash : userHash; 

    HttpHeaders headers = new HttpHeaders(); 
    headers.add("Authorization", sender); 
    headers.add("Content-Type", "application/json"); 
    HttpEntity<T> entity = new HttpEntity<>(body,headers); 
    ResponseEntity<T> responseEntity = restTemplate.exchange(path, HttpMethod.POST, entity, (Class<T>) body.getClass()); 
    return responseEntity; 
} 

cast body.getClass()する必要がありますが、クラスオブジェクトを渡す必要があり、次のように

<T> ResponseEntity<T> makeApiCall(String path, HttpMethod httpMethod, T body, boolean isAdmin){ 

     String sender = isAdmin ? adminHash : userHash; 

     HttpHeaders headers = new HttpHeaders(); 
     headers.add("Authorization", sender); 
     headers.add("Content-Type", "application/json"); 
     HttpEntity<T> entity = new HttpEntity<>(body,headers); 
     ResponseEntity<T> responseEntity = restTemplate.exchange(path, HttpMethod.POST, entity, body.getClass()); 
     return responseEntity; 
    } 

私はcurrenty持っているコンパイルエラーがありますパラメータとして明示的に指定します。

+1

ジェネリックキャストは、処理すべき警告を発生させます。 –