#java #lambda #java-8 #factory #supplier
#java #лямбда #java-8 #фабрика #поставщик
Вопрос:
Я пытаюсь создать объекты (реализовать шаблон factory), используя Java 8 lambda и Supplier
интерфейс.
public static void main(final String[] args) {
FactoryEnum.getEnumByClassName("CLASS_A").getSupplier().execute();
FactoryEnum.getEnumByClassName("CLASS_B").getSupplier().execute();
}
enum FactoryEnum {
CLASS_A(() -> A::new),
CLASS_B(() -> B::new);
private final Supplier<IConverter> supplier;
FactoryEnum(final Supplier<IConverter> supplier) {
this.supplier = supplier;
}
public static FactoryEnum getEnumByClassName(final String className) {
return FactoryEnum.valueOf(className);
}
public IConverter getSupplier() {
return supplier.get();
}
}
interface IConverter {
void execute();
}
class A implements IConverter {
@Override
public void execute() {
System.out.println("Inside A"); //$NON-NLS-1$
}
}
class B implements IConverter {
@Override
public void execute() {
System.out.println("Inside B");
}
}
Когда я звонил FactoryEnum.getEnumByClassName("CLASS_A").getSupplier().execute()
, я ожидал, что это вернет вновь созданный объект класса A, FactoryEnum.getEnumByClassName("CLASS_A").getSupplier().execute()
а это вернет вновь созданный объект класса B. В то время как он возвращает мне лямбду. Почему он возвращает лямбда, а не объект IConverter
. И как я могу это получить?
Комментарии:
1. Вопрос был закрыт до того, как я смог отправить свой ответ. Хотя это опечатка, я думаю, что объяснение того, почему это опечатка, может быть полезным. Вот оно pastebin.com/Q6bxCZhg
2. Кстати, нет смысла создавать дополнительный метод
getEnumByClassName
, который выполняет то же самое, что и уже существующийvalueOf
метод, особенно когда его единственная функция, отличное имя, вводит в заблуждение, поскольку аргумент не является именем класса.3. @Michael: Спасибо за вашу помощь. Я написал это намеренно, потому что на самом деле я получил интерпретацию A::new для new A() , в то время как it is () -> {new A()} .
4. @Holger Да, это имеет смысл. Спасибо, что упомянули об этом.
Ответ №1:
CLASS_A(() -> A::new)
означает
CLASS_A(() -> { return A::new; })
что означает
CLASS_A(() -> { return () -> { new A(); }; })
это не то, что вы пытались передать.
Попробуйте
CLASS_A(A::new)
Комментарии:
1. или
CLASS_A(() -> new A())
🙂