2017-01-17 9 views
0

私はこの質問をしばらく尋ねられたように知っていますが、とにかく自分のコードに適用できるものは見つけられません。多分私はすべてを完全に理解していなかったからかもしれない。私はちょうど@SuppressWarnings("unchecked")解決策を避けたいです。だから私のコードのための新しいアーキテクチャを見つける。ジェネリックとチェックされていないキャスト

私はジェネリック型にキャストしようとしたとき、私は、この行で警告Unchecked cast:com.example.reader.models.SearchableBook to Tを持っている:(T)epubReader.readEpub(fileInputStream)

public class BookHelper { 
    public static <T> T openBook(String ebookFilePath, boolean searchable) { 
     T book = null; 
     EpubReader epubReader = new EpubReader(); 
     FileInputStream fileInputStream = null; 

     try { 
      fileInputStream = new FileInputStream(ebookFilePath); 
      book = searchable ? (T)new SearchableBook(epubReader.readEpub(fileInputStream)) : (T)epubReader.readEpub(fileInputStream); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      try { 
       fileInputStream.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
     return book; 
    } 
} 

私はこのBookHelper方法は非常によく似た2を持つ回避帳やSearchableBookを返すことができますしたいので、私はジェネリックを使用メソッド。

私はこのような何かを行うメソッドにパラメータとして型を送信しようとしましたが、私はまだ同じ警告があります。それがすべてで安全ではないではありませんので、私はSuppressWarningsを使用することができますが、私はこの正しい方法をしたいと思っこの最後の場合には

public static <T> T openBook(String ebookFilePath, boolean searchable, Type t) { 
    T book = null; 
    EpubReader epubReader = new EpubReader(); 
    FileInputStream fileInputStream = null; 

    try { 
     fileInputStream = new FileInputStream(ebookFilePath); 
     if(t instanceof Book) { 
      book = (T)epubReader.readEpub(fileInputStream); 
     } else ... 

:私はまだ確かに、私は同じ問題を抱えているように、ジェネリック型を返すことがあります。この場合、人々が一般的にどのように行動するかを知りたい。このインタフェースを実装

public interface Searchable { 

    String findSentence(String words); 
} 

ラッパーのMyBook:私はUpdate 1では、今私は私の検索可能なインタフェースを持っている

...最善の方法は、この警告を避けるために、自分のコードを複製することはないと思います

public class MyBook implements Searchable { 
    private Book mBook; 

    public MyBook(Book book) { 
     this.setBook(book); 
    } 

    public Book getBook() { 
     return mBook; 
    } 

    public void setBook(Book book) { 
     mBook = book; 
    } 

    @Override 
    public String findSentence(String words) { 
     return null; 
    } 
} 

マイopenBook(String ebookFilePath, boolean searchable)方法:

MainActivityで

protected void onCreate(Bundle savedInstanceState) { 
... 
     MyBook searchBook = BookHelper.openBook(BOOK0_PATH, true); 
     Book book = BookHelper.openBook(BOOK1_PATH,false).getBook(); 
...  
} 

それは、コードの複製で、動作しますが。私がブックをインスタンス化したいのであれば、ラッパーをインスタンス化し、getterを呼び出すgetBook()。しかし、を導入するために使用された資源には、私はBookのために必要ではないがどうなるのだろうか?検索可能な書籍(MyBookラッパー)に固有の検索機能=>findSentence()の実装で使用されるリソースについて説明しています。それらは私のOpenBookメソッドでのみ使用され、GCはそれらをクリアしますか? 。実際、私はそれが以前考えられなかった理由を理解できないほど単純です。

しかし、インターフェイスの目標は何ですか?なぜなら、MyBookクラスにはいくつかのメソッドがあり、誰も必須ではないので、インターフェイスを配置する必要はないからです。私は明確だと思う。

答えて

1

あなたはこのような何か定義した場合について:

public static <T extends Book> T openBook(String ebookFilePath, boolean searchable)

更新:

フィールドとしてBook含まラッパーMyBookを作成します。次に、インターフェイスSearchableを作成し、MyBookに実装します。その後、ジェネリックを削除することができます

public static MyBook openBook(String ebookFilePath, boolean searchable)

をフィールドBookのgetterとsetterを作成します。

+0

したがって、私のジェネリック型はBookから継承されます。これはどうやって動くのだろう? TがBookを拡張する場合、SearchableBookをTにキャストできません。 – Laurent

+0

私は 'SearchableBook'が' Book'を拡張すると思っています...もしそうでなければ、ジェネリックタイプの代わりにインターフェースを使うことをお勧めします。 – beeb

+0

'public static T openBook(String ebookFilePath、boolean searchable)'と 'SearchableBook'を使うと' Book'が拡張されます。 – Laurent

0

チェック例外にする:void f()throws IllegalArgumentExceprion;

+0

'public static T openBook(String ebookFilePath、boolean searchable)throws IllegalArgumentException {...}'にはまだ警告があります。 – Laurent

-1

ジェネリックを使用する代わりにインターフェイスを作成することを考えましたか?このようにして、BookやSearchableBookはそれを実装でき、キャストは問題にならないでしょう。

編集:

が実際にすべてのジェネリックを使用してもロジックがありません、あなたはこのようなインターフェイスにあなたのジェネリックを変更することができます:public interface BookBehaviour { Object readEpub(FileInputStream fileInputStream); }その後、あなたのクラスSearchableBookはBookBehaviourを実装する必要がありますし、またあなたの方法readEpub(FileInputStreamのは)返す必要がありますBookBehaviourタイプです。

+0

だから?私がうまく理解できれば、BookBehaviourを実装しているブックとSearchableBookクラスを持っています。それから私は各クラスのreadEpub()メソッドを実装する必要がありますし、私のコードはまだ複製されていますか? – Laurent

0

私は結局アーキテクチャを変更しました。

私はこのEbookクラスをEpublibから使い、特定の単語を含む文章を検索する機能を追加して、SearchableBookクラスの目的を達成しました。

import nl.siegmann.epublib.domain.Book; 

public class SearchableBook { 
    private Book mBook; 

    // Find a sentence containing the words in parameters 
    public Sentence findSentence(String[] wordsToFind) { ... } 

    ... 
} 

まず私がしようとしたEpublib Bookクラスを拡張しますが、その後、私はSearchableBookにブックをキャストすることはできません実現し、これが私の計画について、私にとって問題でした。そこでこのトピックで説明したこの他のアプローチを試しました。ブックを拡張するが、これの複製を避けるために、プロパティとBookHelperクラスとしてブックを持っていないSearchableBookクラスの作成:説明したようBookSearchableBookクラスでこのコードを使用することができるようにするに

EpubReader epubReader = new EpubReader(); 
FileInputStream fileInputStream = null; 

try { 
    fileInputStream = new FileInputStream(ebookFilePath); 
    book = epubReader.readEpub(fileInputStream); 
} catch (IOException e) { 
    e.printStackTrace(); 
} finally { 
    try { 
     fileInputStream.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

を私が(試してみました私の質問に)私のBookHelperクラスでこれを行う:

public static <T> T openBook(String ebookFilePath, boolean searchable) throws IllegalArgumentException { 
     T book = null; 
     EpubReader epubReader = new EpubReader(); 
     FileInputStream fileInputStream = null; 

     try { 
      fileInputStream = new FileInputStream(ebookFilePath); 
      book = searchable ? (T)new SearchableBook(epubReader.readEpub(fileInputStream)) : (T)epubReader.readEpub(fileInputStream); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      try { 
       fileInputStream.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
     return book; 
    } 

しかし、チェックされていないキャストの問題を得た。

私はその後Interfaceを使用しようとしました:

public interface BookBehaviour { Object read(String ebookFilePath); } 

しかし、私は私のSearchableBookクラスでこのreadメソッドを実装しなければならなかった、読み取りを実現することができるように私の検索できない書籍のために別のクラスを追加する必要があります私は最初の問題、複製に戻った。

最後に、私は簡単なアプローチに戻りました。これ以上の継承、インターフェース、ジェネリックまたはリフレクションは...を受け取り、検索機能を実装するBookHelperクラスを作成したばかりです。それから、私は2つの本をインスタンス化することができます。私はBookHelperクラスを使用し、もう1つは使用しません。このBookHelperクラスには、本を開き、InputStreamコードの複製を避ける方法が含まれています。

私はこれらのより複雑なものを使いたいと思っています。なぜなら私は誰もが自分のプロジェクトで使うことを見ているからです...しかし、私はコンセプトを理解してそれについて読むことを始めても、私のプロジェクトでは、このようなものが必要です。

あなたがより良い命題を持っているなら、この質問に対するより良い答えをお持ちであれば大歓迎です。

関連する問題