2014-01-15 3 views
2

Как реализовать следующий псевдокод в Java?Java: Как реализовать переключатель класса?

Object getInstance(Class<?> type) 
{ 
    switch (type) 
    { 
    case A.class: 
     return createA(param1, param2); 
    case B.class: 
     return createB(param3, param4, param5); 
    default: 
     throw new AssertionError("Unknown type: " + type); 
    } 
} 

Я знаю, что, вероятно, может осуществить это с помощью Map<Class<?>, Callable<Object>> (классов отображения к методу, который возвращает объект), но есть более эффективный/читаемый способ сделать это?

ОБНОВЛЕНИЕ: Извините за вводящий в заблуждение псевдокод. Я не хотел подразумевать, что классы имеют конструкторы без аргументов. Каждый класс построен по-разному. Я знаю, что if-else работает, но это не очень хорошо с точки зрения эффективности. Оно включено).

+0

'switch' в Java очень ограничен. Вы можете включить строки и цифры, вот и все. Я не уверен, что буду спорить о том, чтобы использовать имя типа (string) в качестве переключателя .., который оставляет альтернативу переключения от переключателя. – user2864740

+1

@ user2864740 - включите Enums. Невозможно сделать это на объектах вообще. – Krease

+0

@ Крис. Правда, я все еще группирую их вместе с цифрами в голове. Я виню C#:> – user2864740

ответ

0

Вместо того, чтобы использовать switch, просто используйте if.

if (type == A.class) { 
    return new A(); 
} else if (type == B.class) { 
    return new B(); 
} else { 
    throw new AssertionError("Unknown type: " + type); 
} 

Таким образом, вы можете также обрабатывать более подробные случаи в ваших if условиях, как подклассы, или интерфейсов и т.д. Это также позволяет вашим конструкторам содержать другие аргументы (следуя на заводе, как шаблон), который становится сложнее, если вы просто выбросите их на карту или используйте отражение.

0

Вы можете использовать if else if заявление:

if (type.equals(A.class)) { 
    return new A(); 
} else if (type.equals(B.class)) { 
    return new B(); 
} else { 
    new AssertionError("Unknown type: " + type); 
} 
2

Как об использовании Class объекта, чтобы создать новый экземпляр?

private static final Set<Class> ALLOWED_CLASSES = 
    new HashSet<>(Arrays.asList(A.class, B.class)); 

Object getInstance(Class<?> type) { 
    if (!ALLOWED_CLASSES.contains(type)) { 
     throw new AssertionError("Unknown type: " + type); 
    } 
    return type.newInstance(); 
} 
+0

+1 - с оговоркой, что это работает только в том случае, если класс имеет нулевой конструктор –

+0

Я думаю, что это потерпит неудачу, если это внутренний класс –

+0

Дубликат http://stackoverflow.com/a/21130129/14731 (и выиграл ' т по той же причине). – Gili

0

Если все конструкторы вызываются без параметров,

Object getInstance(Class<?> type) { 
    return type.newInstance(); 
} 

В противном случае, если количество вариантов мало, используйте if statements, иначе использовать карту как задумано.

+0

Дубликат http://stackoverflow.com/a/21130129/14731 – Gili

0

Если ни один из вызовов new не требует параметров, вы можете использовать newInstance(). Затем просто добавьте код ошибки:

private static final List<Class> classes = Arrays.asList(A.class, B.class, ...); 

public static Object getInstance(Class<?> type) { 
    if (classes.contains(type)) 
     return type.newInstance(); 
    throw new AssertionError("Unknown type: " + type); 
} 
+0

Извините за вводящий в заблуждение псевдокод. Я не имел в виду, что классы имеют конструкторы без аргументов.Каждый тип имеет свой собственный механизм построения (разные параметры для разных классов). Спасибо, в любом случае. – Gili

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