簡體   English   中英

Java通用類型實例化

[英]Java Generic type instantiation

像這樣的問題很多,但是似乎沒有一個問題可以專門回答我的問題。

您如何實例化新的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

任何建議,將不勝感激!

我認為一種常見的方法是要求像這樣傳遞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...

  }
}

除了傳遞Class對象並像johncarl的答案中那樣使用反射之外 ,還可以使用泛型工廠:

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);

您無需在此處使用參數來調用方法。 因為您有靜態方法,足以直接從MyClass訪問fromInputStream方法,我的意思是:

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

希望對您有幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM