使用泛型作为参数

Using Generics as Parameters

我对 Java 和 Android 还是很陌生,我正在做一个 Android RSS reader 项目。我正在编写作为 AsyncTask 运行的 reader,并希望尽可能保持它的可重用性。我在 reader 中使用 SAX 解析器,并希望它接受扩展 DefaultHandler 的任何类型的处理程序。但是,当我尝试调用 SAXParser 的解析方法时,它不理解处理程序参数。

cannot resolve method 'parse(org.xml.sax.InputSource,java.lang.Class<capture<? extends org.xml.sax.helpers.DefaultHandler>>)'

就传递通用处理程序而言,这是解决此问题的正确方法吗?还是我应该做一些不同的事情?

public class RSSFeeder extends AsyncTask<Void, Void, Void>{

private Class<? extends DefaultHandler> handler;
private String feedURL;

public RSSFeeder(Class<? extends DefaultHandler> handler, String feedURL) {
    this.handler = handler;
    this.feedURL = feedURL;
}

@Override
protected Void doInBackground(Void... params) {
    URL feedLocation = null;
    try {
        feedLocation = new URL(feedURL);
        BufferedReader in = new BufferedReader(new InputStreamReader(feedLocation.openStream()));

        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser sp = spf.newSAXParser();

        sp.parse(new InputSource(in), handler);

    } catch (MalformedURLException murlex) {
        Log.d(this.getClass().getName(), "The supplied URL is not valid " + murlex.getMessage());
    } catch (IOException iox) {
        Log.d(this.getClass().getName(), "Could not read data from the supplied URL: " + feedLocation.toString() + " " + iox.getMessage());
    } catch (ParserConfigurationException pcex) {
        Log.d(this.getClass().getName(), "Could not configure new parser. " + pcex.getMessage());
    } catch (SAXException saxex) {
        Log.d(this.getClass().getName(), "Could not create new sax parser. " + saxex.getMessage());
    }

    return null;
}

handler 是类型 java.lang.Class 的变量,而不是 DefaultHandler (或其任何子类型)。方法 SAXParser#parse() 的第二个参数必须是 DefaultHandler 类型。您可以尝试将 class 声明为泛型 class,类型参数扩展为 DefaultHandler:

public class RSSFeeder<T extends DefaultHandler> extends AsyncTask<Void, Void, Void>{
   private T handler;

   public RSSFeeder(T handler, String feedURL) {
      this.handler = handler;
      this.feedURL = feedURL;
   }
   ...

}