2012-02-25 4 views
3

Я работаю над java-приложением. Модель абстрактного класса и 2 производных класса Model 1 и Model 2. Model1 и Model2 ведут себя по-разному, поэтому я хочу разрешить пользователю выбирать модель из двух. Он может быть реализован как:Java, список классов

Model model; 
If(response==1){ 
    model = new Model1(); 
}else if(response==2){ 
    model = new Model2(); 
} 

Теперь проблема состоит в том, что если я добавить новый класс Model3, я должен переписать код. Я мог бы создать список, где я бы добавил экземпляр из каждого класса, тогда я бы добавил статический метод, который вернет новый экземпляр класса, но я надеюсь, что это может быть сделано с бит более стильным.

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

Возможно ли создать List<Class>, а затем использовать объект класса как конструктор для создания экземпляра данного класса?

ответ

4

Вы можете создать список suppliers:

static final List<Supplier<Model>> MODEL_MAKERS = ImmutableList.of(
    new Supplier<Model>() { public Model get() { return new Model1(); } }, 
    new Supplier<Model>() { public Model get() { return new Model2(); } }, 
    new Supplier<Model>() { public Model get() { return new Model3(); } } 
); 

Вы могли бы гадость вокруг с отражением, но это требует выходит за рамками обычных механизмов обработки исключений Явы, требует без аргументов public конструкторов и public классов, которые ограничивают то, как код могут меняться при обслуживании способами, которые не проверяются javac, и просто не нужно в этом случае.

+0

+1 для не использующего отражение.Иногда вам приходится, хотя (если вы не знаете класс во время компиляции, например) –

+0

@StevenSchlansker, я согласен, что есть использование для отражения. Я предпочитаю ограничивать его границ между объектными системами Java и другими системами - файловой системой, ORM, встроенными скриптовыми языками. Если вы полностью работаете в Java, часто есть лучший способ использовать его, что не влияет на способность ретрансляторов координировать, следовать потоку программы и т. Д. –

1

Если вы уверены, что он будет иметь открытый конструктор без арг, вы можете использовать Class.newInstance()

Для более сложных применений, вы можете найти Constructor объект с Class.getConstructor(s) и затем вызвать его таким образом.

Как только у вас есть это, относительно легко вставить свои Class es в Map или что-то делать поисками и создавать экземпляры.

+0

Не используйте 'newInstance'. [Javadoc] (http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#newInstance%28%29) явно предупреждает: «Обратите внимание, что этот метод распространяется на любое исключение, нулевой конструктор, включая проверенное исключение. Использование этого метода эффективно обходит проверку исключения времени компиляции, которая в противном случае была бы выполнена компилятором ». –

+0

В некоторых случаях это именно то, что вы хотите. Это определенно стоит отметить. –

0

Да, вы можете использовать метод newInstance() для класса для его построения. Однако он должен иметь конструктор no-args.

+0

Не используйте 'newInstance'. [Javadoc] (http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#newInstance%28%29) явно предупреждает: «Обратите внимание, что этот метод распространяется на любое исключение, нулевой конструктор, включая проверенное исключение. Использование этого метода эффективно обходит проверку исключения времени компиляции, которая в противном случае была бы выполнена компилятором ». –

+0

Это нормально, если вы уверены, что конструктор не будет генерировать исключение. Если вы никогда не вызывали ничего, что могло бы вызвать исключение, вы бы никогда не получили никакого кодирования ... :-) –

+0

это нормально, если вы уверены, что конструктор не будет генерировать исключение ** сейчас и под обслуживание **. –

Смежные вопросы