2017-12-06 5 views
1

私はコードを改良して、特にGenericクラスを使用する方法を改善したいと思います。私は私のエンティティIDのみ1時間の代わりのようなサービスでGenericEntityで1つずつのクラスを指定したいJavaは、constまたは静的メソッドを持つ汎用クラスのparamを定義します。

GenericEntity<T extends Serializable>{ 

    protected T id; 
    public T getId(){ return id;}; 
... 
} 

public class A extends GenericEntity<Integer>{ 
    ... 
} 


public interface IService<T extends GenericEntity, T extends Serializable>{ 
... 
} 

public class AService extends IService<A,Integer>{ 
... 
} 

:私のプロジェクトで は、私はfolowingのような約30のクラスがあります。

public class A extends GenericEntity<getIdType()>{ 
    public final static Class getIdType(){ 
     return Integer.class; 
    } 
} 

public class AService extends IService<A,A.getIdType()>{ 
... 
} 

私はそれがうまくいかないことを知っていますが、私はそれを行う方法があると思っています。 ご協力いただきありがとうございます。

class GenericEntity<T extends Serializable>{ 
    protected T id; 
    public T getId(){ return id;}; 
} 

// THESE ARE UNNECESSARY as far as I can tell 
class A extends GenericEntity<Integer>{ } 
class B extends GenericEntity<Long>{ } 

// where U matches the generic type of GenericEntity<?> 
interface IService<T extends GenericEntity<?>, U extends Serializable>{ } 

class AService extends IService<A, Integer>{ } 
class BService extends IService<B, Long>{ } 

あなたがこれを行うことができます:代わりの

+0

なぜそれをしたいですか? 'AService'を宣言すると、' A'クラスとそのID型の両方が分かります。 – daniu

+0

'IService >' ...そして、 'AServiceはIService を実装していますか? – user2478398

+0

私はいつか、私はそれを行うために約60の変更を持つ整数の代わりにロングを使用する必要がある場合はしたい。 私もId型が必要な単体テストがあります – ScorprocS

答えて

1

class GenericEntity<T extends Serializable> { 
    protected T id; 
    public T getIdFromEntity() { return id; } 
} 

// 'IService' can/should only know of 'id' as some type that extends 'Serializeable' 
// So if something implements 'IService' then everything knows it will have 
// a method with the signature 'T getGenericEntity(Serializable id);' 
interface IService<T extends GenericEntity<?>> { 
    public T getGenericEntity(Serializable id); 
} 

// 'AService' knows that 'id' will be an 'Integer' 
class AService implements IService<GenericEntity<Integer>> { 

    Map<Serializable, GenericEntity<Integer>> entityMap = new HashMap<>(); 

    void someMethod() { 
     GenericEntity<Integer> entity = this.getGenericEntity(Integer.valueOf(1)); 
     Integer i1 = entity.getIdFromEntity(); 
     // ... do stuff 
    } 

    // even though 'AService' knows that 'id' will be an 'Integer' 
    // the 'IService' interface defines this as taking a 'Serializable' 
    // so it must keep that method signature. 
    @Override public GenericEntity<Integer> getGenericEntity(Serializable id) { 
     return entityMap.get(id); 
    } 
} 

class BService implements IService<GenericEntity<Long>> { 
    @Override public GenericEntity<Long> getGenericEntity(Serializable id) { return null; } 
    // ... similar to AService ... 
} 

これは、すべての余分なclass X extends GenericEntity<SOME_TYPE>クラスを切り取ってしまいます。

GenericEntity<T extends Serializable>の汎用品とinterface IService<T extends GenericEntity<?>>の1つが必要です。また、AServiceBServiceは、Serializeable(整数と長整数)を拡張する実際の型を知っているので、ジェネリックで渡された余分な情報は必要ありません。 IService以来

はどのT extends GenericEntity<?>ための一般的なものであり、それはは(、あなたはおそらくにそれを望んでいないはずです)genericEntity.getId()ための具体的な種類を知っているべきではありません。また、Interfaceなので、具体的にするのは避けてください。 IService<GenericEntity<?>>class GenericEntity<T extends Serializeable>はそれを必要とするので、ワイルドカード?Serializeableを拡張することを意味するので

id限りIServiceとして心配のタイプは、Serializableあります。

+0

あなたの投稿をありがとうございます。あなたの例では、サービスがエンティティIDのタイプをどのように知っているのだろうか? インターフェイスIService > { public T getGenericEntity(?id); } – ScorprocS

+0

@ScorprocSが編集されました。それはあなたの質問に答えますか? – xtratic

+0

ありがとうございます。ですから、IDで一般的なエンティティを取得するには、それを行うだけです。 インターフェイスIService > {public T getGenericEntity(Serializable id);} } – ScorprocS

関連する問題