Другое решение, которое вы можете рассмотреть, заключается в следующем:
Map<Integer, Class<? extends Processor>> map = new HashMap<>();
// Integer.valueOf(x) used to prevent autoboxin just a matter of opinion.
map.put( Integer.valueOf( 0 ), MyProcessor.class );
Processor chosen = map.get( userIn ).getConstructor( String.class ).newInstance( projectKey );
launcher.addProcessor(chosen);
Это в основном то же самое, но разница в том, что возвращаемый объект имеет тип Processor
, и класс определенно существует.Когда вы используете String и Class.forName(...)
, есть два дополнительных исключения, которые могут быть выброшены.Сначала ClassNotFoundException
, который будет выдан, если метод Class.forName()
не нашел класс для данного имени.Второе дополнительное исключение - ClassCastException
, которое будет выброшено, если созданный объект не является реализацией или подклассом Processor
.
Объяснение:
Мы используем карту с Integer
в качестве нашего ключа и Class<? extends Processor>
в качестве нашего значения.Объект Class<T>
может рассматриваться как объектное представление соответствующего файла .class (технически некорректно, но для простоты мы предполагаем, что так оно и есть).Что означает <? extends Processor>
в бетоне?Это означает, что карта будет разрешать только значения классов, которые являются реализацией или подтипом Processor
.Это исключает поток ClassCastException
, потому что, если мы можем хранить только классы, расширяющие Processor, мы можем извлекать только те классы, которые могут быть преобразованы в Processor
без каких-либо проблем или даже из одного потока.
Примечание: Я включил процесс создания экземпляра, который обычно является плохой идеей в продуктивной среде, но он значительно сокращает код, и нет необходимости дополнительно его объяснять, поскольку вы используете точно такой же подходв вашем собственном ответе.