Java通用类型实例化

时间:2012-03-31 20:20:12

标签: java generics generic-programming

有很多这样的问题,但他们似乎都没有具体回答我的问题。

如何实例化新的T?

我有一个泛型方法,我需要在type参数中返回一个新类型的实例。 这是我的代码......

class MyClass {

  public static MyClass fromInputStream( InputStream input ) throws IOException {

    // do some stuff, and return a new MyClass.

  }
}

然后在一个单独的类中,我有一个像这样的通用方法......

class SomeOtherClass {

  public <T extends MyClass>download(URL url) throws IOException {

    URLConnection conn = url.openConnection();

    return T.fromInputStream( conn.getInputStream() );

  }
}

我也试过以下......

class SomeOtherClass {

  public <T extends MyClass>download(URL url) throws IOException {

    URLConnection conn = url.openConnection();

    return new T( conn.getInputStream() ); // Note my MyClass constructor takes an InputStream...

  }
}

但上述的排列都不会编译! 错误是:

File: {...}/SomeOtherClass.java
Error: Cannot find symbol
symbol : class fromInputStream
location : class MyClass

任何建议都将不胜感激!

3 个答案:

答案 0 :(得分:6)

我认为一种常见的方法是要求传递类型T的类,如下所示:

class SomeOtherClass {

  public <T extends MyClass> T download(Class<T> clazz, URL url) throws IOException {

    URLConnection conn = url.openConnection();

    return clazz.getConstructor(InputStream.class).newInstance(conn.getInputStream() ); // Note my MyClass constructor takes an InputStream...

  }
}

答案 1 :(得分:2)

除了传递Class对象并使用johncarl's answer中的反射之外,您可以使用通用工厂:

public abstract class InputStreamFactory<T> {

    public T make(InputStream inputStream) throws IOException;
}

并修改download

public <T extends MyClass> T download(URL url, InputStreamFactory<? extends T> factory) throws IOException {

    URLConnection conn = url.openConnection();

    return factory.make(conn.getInputStream());
}

每个MyClass派生可以提供自己的工厂实现:

public class MySubClass extends MyClass {

    public static final InputStreamFactory<MySubClass> FACTORY =
            new InputStreamFactory<MySubClass>() {
                @Override
                public MySubClass make(InputStream inputStream) throws IOException {
                    return new MySubClass(inputStream); //assuming this constructor exists
                }
            };
}

调用者可以参考它:

MySubClass downloaded = new SomeOtherClass().download(url, MySubClass.FACTORY);

答案 2 :(得分:0)

您无需在此处使用参数来调用方法。因为你有静态方法,就足以直接从MyClass访问 fromInputStream 方法,我的意思是:

return MyClass.fromInputStream( conn.getInputStream() );

希望它能帮到你