Ссылка на Java-потребительский метод для нестатических методов

#java #method-reference #functional-interface

#java #метод-ссылка #функциональный интерфейс

Вопрос:

Фрагмент кода:

 class Scratch {

Map<ActionType, SomeConsumer<DocumentPublisher, String, String>> consumerMapping = Map.of(
        ActionType.REJECT, DocumentPublisher::rejectDocument, 
        ActionType.ACCEPT, DocumentPublisher::acceptDocument,
        ActionType.DELETE, DocumentPublisher::deleteDocument);
        

private void runProcess(DocumentAction action) {
    DocumentPublisher documentPublisher = DocumentPublisherFactory.getDocumentPublisher(action.getType);

    SomeConsumer<DocumentPublisher, String, String> consumer = consumerMapping.get(action.getType());
    consumer.apply(documentPublisher, "documentName", "testId1");
}

private interface DocumentPublisher {
    
    void rejectDocument(String name, String textId);

    void acceptDocument(String name, String textId);

    void deleteDocument(String name, String textId);
}
  

}

Какой тип функционального интерфейса я могу использовать вместо SomeConsumer? Основная проблема здесь в том, что это не статическое поле, а объект, который я узнаю только во время выполнения.

Я пытался использовать BiConsumer, однако он говорит мне, что я не могу ссылаться на нестатический метод таким образом.

Ответ №1:

Из вашего использования здесь:

 consumer.apply(documentPublisher, "documentName", "testId1");
  

Совершенно ясно, что потребитель использует 3 вещи, так что это не BiConsumer . Вам понадобится TriConsumer , которого нет в стандартной библиотеке.

Вы можете написать такой функциональный интерфейс самостоятельно, хотя:

 interface TriConsumer<T1, T2, T3> {
    void accept(T1 a, T2 b, T3 c);
}
  

Если единственными общими параметрами, которые вы когда-либо собираетесь ему предоставить, являются <DocumentPublisher, String, String> , я думаю, вам следует назвать это чем-то специфичным для вашего приложения, например DocumentPublisherAction :

 interface DocumentPublisherAction {
    void perform(DocumentPublisher publisher, String name, String textId);
}

Map<ActionType, DocumentPublisherAction> consumerMapping = Map.of(
        ActionType.REJECT, DocumentPublisher::rejectDocument, 
        ActionType.ACCEPT, DocumentPublisher::acceptDocument,
        ActionType.DELETE, DocumentPublisher::deleteDocument);
        

private void runProcess(DocumentAction action) {
    DocumentPublisher documentPublisher = DocumentPublisherFactory.getDocumentPublisher(action.getType);

    DocumentPublisherAction consumer = consumerMapping.get(action.getType());
    consumer.perform(documentPublisher, "documentName", "testId1");
}