2017-07-12 8 views
0

私は以下のコードを持っています。私は、インジェストメソッドでHandlerのraw型を使用していることから、いくつかのチェックされていない警告が出ています。私は生のタイプの警告と私の使用法を削除するための最善の方法に立ち往生しています。私の主な障害は、インジェストメソッドのパラメータがIV2GraphObjectであり、ハンドラでハンドルメソッドを呼び出そうとすると、ハンドラに境界を設定しようとするとコンパイルエラーが発生するということです。未処理の生の型警告への呼び出しを修正しました。Java

public class IV2Ingestor implements Ingestor<IV2GraphObject> { 
    public interface Handler<T extends IV2GraphObject> { 
    void handle(T iv2Object); 

    Set<? extends Element> getNewElements(); 
    } 

    // map of handlers for supported objects 
    private Map<Class<? extends IV2GraphObject>, Handler<? extends IV2GraphObject>> handlers; 

    public static IV2Ingestor getInstance(VisalloEnv environment) { 
    // create a new instance 
    IV2Ingestor ingestor = new IV2Ingestor(); 

    ingestor.handlers = new HashMap<>(); 
    ingestor.handlers.put(Tweet.class, new TweetHandler(graphFactory)); 
    ingestor.handlers.put(TwitterUser.class, new TwitterUserHandler(graphFactory)); 
    ingestor.handlers.put(GoogleNews.class, new GoogleNewsHandler(graphFactory)); 
    ingestor.handlers.put(VKPost.class, new VKPostHandler(graphFactory)); 
    ingestor.handlers.put(YouTube.class, new YouTubeHandler(graphFactory)); 
    ingestor.handlers.put(Instagram.class, new InstagramHandler(graphFactory)); 

    // return ingestor 
    return ingestor; 
    } 

    @Override 
    public void ingest(IV2GraphObject ingestable) { 
    Class<? extends IV2GraphObject> ingestableClass = ingestable.getClass(); 

    if (handlers.containsKey(ingestableClass)) { 
     Handler handler = handlers.get(ingestableClass); 

     try { 
      handler.handle(ingestable); 
     } finally { 
      // persist changes 
      graph.flush(); 

      // notify GPWs of any new graph elements 
      workQueueRepository.pushElements(handler.getNewElements(), Priority.LOW); 
     } 
    } 
    } 
+0

コンストラクタではなく、「getInstance」があるのはなぜですか?シングルトンではないようです。なぜ、「VisalloEnv環境」を使うのですか? 'graphFactory'とは何ですか? 'ハンドラー 'に追加するこれらのクラスは何ですか?実際のエラーは何ですか? –

+1

私は、与えられた構造で警告を完全に避ける方法はないと思います。それはちょうどあなたがどんな警告をしたいのか、どこで警告するのかという問題です。 – shmosel

+0

'@SuppressWarnings(" rawtypes ")'が動作しないのはなぜですか?このコードがどのようにコンパイルされるのかわかりませんが、 –

答えて

0

まず、あなたは、各Class<T>Handler<T>にマッピングすることにしたいハンドラへのクラスからマップを持っていますが、地図の種類とその関係を表現することはできません。これを安全に行うには、引数の型と戻り値に関係を強制する新しいクラスを作成して、getput(このクラスは内部的に未チェックのキャストが残っていますが、クラスのAPIはこれが安全であることを保証します):

class ClassToHandler { 
    private Map<Class<? extends IV2GraphObject>, Handler<? extends IV2GraphObject>> map 
     = HashMap<>(); 

    @SuppressWarnings("unchecked") 
    public <T extends IV2GraphObject> Handler<T> get(Class<T> clazz) { 
     return (Handler<T>)map.get(clazz); 
    } 

    public <T extends IV2GraphObject> void put(Class<T> clazz, Handler<T> handler) { 
     map.put(clazz, handler); 
    } 
} 

あなたはhandlersをこのクラスの対象とします。これにより、handlers.get()への呼び出しがより良いタイプに戻るようになります。

第二の問題はingestable.getClass()リターンがあまりにも緩く(IV2GraphObjectある)ingestableのタイプが接続されてClass<? extends IV2GraphObject>を入力することです。理想的には、ingestableClassはの場合Class<T>となり、の場合はTとなります。そうすれば、handlers.get(ingestableClass)Handler<T>を返し、handler.handle(ingestable)はコンパイルされます。

.getClass()の戻り値の型で? extends理由は(実際には、ここでは、それは常にサブタイプでなければなりません)ingestableの実際のランタイムクラスがIV2GraphObjectのサブタイプであってもよいことであり、したがって、そのクラスではありませんClass<IV2GraphObject>。しかし、タイプT(オブジェクトの実際の実行時タイプ)が存在します。ingestableTのインスタンスで、ingestable.getClass()Class<T>のインスタンスです。しかし、どうすればそれが得られますかT?コンパイラはまだingestableが同じタイプT(のインスタンスであることを知らない、という我々が行う場合でも、しかし

helper(ingestableClass, ...); 

private <T extends IV2GraphObject> void helper(Class<T> clazz, ...) { ... } 

:我々はヘルパーメソッドを使用して、ワイルドカード?の外にTを取得するためにキャプチャすることができますコンパイラはingestableIV2GraphObjectのインスタンスであることを知っているだけです。クラス.cast()を使用して、警告を出さずにタイプTにキャストすることができます(キャストは常に成功するとわかりますが、警告なしでコンパイルするだけです)、警告を生成する(T)キャストを直接行うこともできます):

public void ingest(IV2GraphObject ingestable) { 
    Class<? extends IV2GraphObject> ingestableClass = ingestable.getClass(); 
    helper(ingestableClass, ingestable); 
} 

private <T extends IV2GraphObject> void helper(Class<T> clazz, IV2GraphObject ingestableTemp) { 
    T ingestable = clazz.cast(ingestableTemp); 
    Handler<T> handler = handlers.get(ingestableClass); 
    try { 
     handler.handle(ingestable); 
    // ... 
} 
関連する問題