Методы прохождения в Java - PullRequest
       27

Методы прохождения в Java

1 голос
/ 05 февраля 2020

Я пытаюсь выполнить sh прохождение метода в Java.

Вот вид с высоты птичьего полета на то, что я пытаюсь сделать в качестве фиктивного примера:

public final class A {
  private String value;

  public A(String value) {
    this.value = value;
  }

  public final Object bind(Function<String, String> func) {
    this.value = func.apply(value);

    return this;
  }

  // Rest of the logic here to deal with `value`
}

public final class B {
  public static void main(String[] args) {
    A<T> a = new A("hello");
    a.bind(B::methodOne).bind(B::methodTwo);
  }

  private String methodOne(String s) {
    // method logic here

    return "haha";
  }

  private String methodTwo(String s) {
    // method logic here

    return "hi";
  }
}

Итак, в основном, у меня есть методы в классе, B в приведенном выше примере, и я хочу передать методы B в A и сохранить возвращаемое значение этого метода B в A для дальнейшей обработки. .

Я пытался использовать method reference функцию Java, но, поскольку я не пишу ежедневно с Java, мне трудно понять, как правильно Сделать это sh при выполнении указанных выше ограничений.

В настоящее время я получаю ошибку incompatible types: invalid method reference при выполнении привязки в основном методе.

Обновление

Внесены изменения в мои ограничения программы.

Ответы [ 2 ]

3 голосов
/ 05 февраля 2020

РЕДАКТИРОВАТЬ: спрашивающий обновил свой вопрос много после прочтения этого ответа. Важно отметить, что изначально каждый метод имел совершенно разные сигнатуры (разные типы параметров и суммы, а также разные типы возвращаемых данных). Я оставляю этот ответ без изменений, имейте в виду, что он больше не относится к вопросу в его нынешнем виде.

Это не очень хорошо работает, потому что методы, которые вы хотите передать, имеют совершенно разные подписи (methodOne's равен (B, String) -> int (почему у вас там заглавная буква I Int, это опечатка?), methodTwo - (B) -> String, а methodThree - (B, String, String) -> String.

В java лямбды должны соответствовать функциональному интерфейсу. Невозможно иметь функциональный интерфейс для переменного числа входных аргументов.

С помощью шаблонов вы можете попытаться описать тот факт, что типы ваших входов и выходов различны каждый раз.

Это действительно звучит как проблема X / Y: у вас есть проблема X (которую вы не объяснили, и мы не знаем, что это такое), и вы подумали: «Я знаю! Я» Я буду использовать лямбды, чтобы абстрагироваться от понятия «метод» ... и теперь вы задаете вопросы об этом.

Но вы задаете неправильный вопрос. Задайте X. Потому что даже если гипотетически Вы можете как-то подогнать свои 3 метода в один и тот же лямбда-тип (вы не можете), тогда вы не сможете их вызывать.

Вот еще одно работоспособное понятие, но я понятия не имею, если это решает ваш X, потому что вы не объяснили это:

@FunctionalInterface
public interface MyXThinger {
    Object result(Object... args);
}

Если вы хотите вызвать это, как вы узнали бы, что конкретный MyXThinger (вы не объяснили, что такое X, поэтому я могу не придумать хорошее имя здесь) работает, если вы передаете 2 строки, и падает, если вы пропустите что-нибудь еще? Вот почему, более или менее, я нахожу описание вашей проблемы недостаточным, чтобы дать solid совет здесь.

1 голос
/ 05 февраля 2020

Вы пишете выражение B::methodOne в статическом c контексте.

Нестатистические c методы имеют невидимый параметр, называемый «получатель»: это экземпляр.

Итак, в контексте c, B::methodOne имеет подпись: (B, String) -> String. Ваш метод связывания хочет (String) -> String, и эти два не совместимы. Следовательно, это не работает.

Существует два способа исправить это:

  1. создать экземпляр: B b = new B(); a.bind(b::methodOne);. Выражение b::methodOne, где b - это переменная типа B, ссылающаяся на фактический экземпляр B (созданный с помощью new B()), ДОЛЖЕН иметь при необходимости подпись (String) -> String.
  2. Сделать methodOne method static, после чего он больше не имеет невидимого параметра B instance.

Ваш код также забит ошибками ладьи ie; Вы должны вызывать a.bind, а не A.bind, используя A и B, поскольку имена классов чрезвычайно запутаны, ваш метод связывания возвращает Object (он должен возвращать A) и т. д. c. Я думаю, что способ исправить это - изучить основы c java; Попытки справиться с этими ошибками понемногу кажутся неподходящими для того, для чего используется stackoverflow. Поэтому я оставляю их в качестве упражнения для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...