Java Тип создания экземпляров - PullRequest
0 голосов
/ 01 апреля 2012

Подобных вопросов много, но, похоже, ни один из них не отвечает конкретно на мой вопрос.

Как вы создаете новый T?

У меня есть универсальный метод, мне нужно вернуть новый экземпляр типа в параметре типа. Вот мой код ...

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 ]

6 голосов
/ 01 апреля 2012

Я думаю, что общий подход состоит в том, что класс 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...

  }
}
2 голосов
/ 01 апреля 2012

Кроме передачи объекта 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);
0 голосов
/ 01 апреля 2012

Вам не нужно использовать параметр здесь для вызова метода. Поскольку у вас есть статический метод, вам будет достаточно доступа к fromInputStream методу напрямую из MyClass, я имею в виду:

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

Надеюсь, это поможет вам

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...