2017-06-28 7 views
0

私はJavaには新しく、具体的にはジェネリックコードを書くことです。私の仕事はResultSetオブジェクトのID列の値を返す汎用関数を書くことです。Javaジェネリックの戻り値:ダブルキャスト

public <T> T getRowId(ResultSet rs) throws SQLException { 
    return (T)((Long)rs.getLong(idCol)); 
} 

だから親クラスで、私は機能になってしまった

親クラスは、整数のIDを持ち、子クラスは、文字列のIDを持っている(私はそれが文字列IDを持っている珍しいです知っているが、データは非常に固有のものです)

と子クラスで私が親を上書きする方法があります:

public <T> T getRowId(ResultSet rs) throws SQLException { 
    return (T)(rs.getString(idCol)); 
} 

をそして、私はこの関数を呼び出す必要があるとき、私はちょうど行います

getRowId(rs) 

私の質問は、ダブルキャストを行う場合です(T)((Long)...)はいいですか?そして私が気づいていないこの機能を実装する簡単な方法はありますか?

+2

いいえ、これは罰金ではありません。 'T'は例えば' String'のようなもので、 'Long'を' String'にキャストすることはできません。 'Function 'をメソッドに渡さない限り、 'long'(総称して' rs.getLong() 'の結果を返すことはできません。 –

+0

string IDはより確かな選択肢ですtbh。 –

+1

Tの正しい具体的な型がLong(resp String)の場合、getRow()メソッドは一般的でTを返しますか?そのコードは意味をなさないが、どのようにしてこのメ​​ソッドを含むクラスとは何ですか?このメソッド(およびそのクラス)の責任は何ですか? –

答えて

0

LongまたはStringが得られていることが正確にわかっている場合、コメントにはTにキャストするのは意味がありません。ここで

2あなたが取ることができるアプローチされています

アプローチ1:

@SuppressWarnings("unchecked") 
public static <T> T getRowId(ResultSet rs) throws SQLException { 
    return (T)rs.getObject(1); 
} 

アプローチ2:

public interface RowMapper<T>{ 
    public T getRowId(ResultSet rs) throws SQLException; 
} 

public class ParentRowMapper implements RowMapper<Long>{ 

    public Long getRowId(ResultSet rs) throws SQLException { 
     return rs.getLong(1); 
    } 
} 

public class ChildRowMapper implements RowMapper<String>{ 

    public String getRowId(ResultSet rs) throws SQLException { 
     return rs.getString(1); 
    } 
} 
+1

アプローチ1を削除してください。それは無謀でひどいアドバイスです。キャストが決して失敗しないことを正当化できない限り(コンパイラが知ることができないことがあるため)、未確認の警告を抑止してはいけません。それを正当化することができれば、抑圧に関するコメントに正当化を追加する必要があります。この場合、安全性を保証することはできません。 –

+0

私はまだ最初のアプローチを破棄しません。コンパイル時には、決して契約や安全性を強制することはできません。列の値が 'T'型であると仮定する必要がある場合があります。文字列に 'resultSet.getLong'を呼び出すのと同じです。 Class をこのメソッドに渡して、 'ClassCastException'を回避したい場合は、追加の検証を行うことができます。 – tsolakp

+0

私はアプローチ#2で終わった、アドバイスをありがとう – Tamara