Java передать метод как параметр

в Java, как вы можете передать тип в качестве параметра (или объявить как переменную)?

Я не хочу прослыть экземпляр типа, но самого типа (например. int, String и т. д.).

В C#, я могу сделать это:

есть ли способ в Java без передачи экземпляр типа t?
Или мне нужно использовать мои собственные константы int или enum?
Или есть лучший способ?

Edit: вот требование для фу:
На основе типа t он генерирует другую короткую xml-строку.
Код в if / else будет очень маленьким (одна или две строки) и будет использовать некоторые переменные частного класса.

6 ответов

вы могли бы пройти Class in.

обновление: путь ООП зависит от функционального требования. Лучше всего было бы определить интерфейс foo() и две конкретные реализации, реализующие foo() а затем просто позвоните foo() о реализации, которую вы имеете под рукой. Другой способ может быть Map , Action> который вы могли бы назвать actions.get(cls) . Это легко сочетается с интерфейсом и конкретными реализациями: actions.get(cls).foo() .

у меня был аналогичный вопрос, поэтому я разработал полный беглый ответ ниже. Мне нужно было передать класс (C) объекту (O) несвязанного класса и заставить этот объект (O) испускать новые объекты класса (C) обратно ко мне, когда я попросил их.

в приведенном ниже примере показано, как это делается. Существует класс MagicGun, который вы загружаете с любым подтипом класса снаряда (Pebble, Bullet или NuclearMissle). Интересно, что вы загружаете его подтипами снаряда, но не фактические объекты этого типа. MagicGun создает фактический объект, когда пришло время стрелять.

Можно ли передать метод в качестве параметра в Java? Если я не могу, то что было бы лучшим способом для метода ниже, без необходимости повторять код.

Я буду вызывать метод rangeChecking из другого класса, и каждый раз, когда я вызываю enterUserInput, метод rangeChecking будет отличаться

Для этого вы должны использовать interface.

Вы передаете интерфейс, объявляющий желаемую функцию, и вызываете желаемый метод. Конкретный метод, который будет вызываться, — это тот, который реализуется реализующим классом.

Не знаю, насколько я знаю. Обычно это делается с помощью интерфейса, который имеет тот метод, который вы хотите, и передачи класса, который реализует этот интерфейс.

Создайте интерфейс с этой сигнатурой метода и передайте анонимный подкласс его реализации вашего метода.

В будущих версиях java (с появлением лямбда) вам не нужно будет определять интерфейс и анонимный внутренний класс — там будет конкретный синтаксис лямбда, который будет компилироваться в эквивалентный байт-код.

Вы можете использовать java-отражение.

Есть способы сделать это, используя Reflection , но это лучше всего избежать. Вы хотите создать интерфейс, например:

Затем создайте реализации для каждого из методов проверки диапазона:

Тогда ваша другая подпись метода будет выглядеть следующим образом:

Чтобы вы могли передать любой из ваших объектов, реализующих интерфейс RangeChecker.

Вы можете создать интерфейс, который определяет необходимый метод, и передать объект класса, который реализует этот интерфейс. Часто для этого используются анонимные классы.

вы не можете передать метод в java.

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

вы могли бы в своем коде создать анонимный класс.

Нет, передача методов в качестве аргумента невозможна.

Я думаю, лучший подход — создать интерфейс, написать класс, который реализует это (модифицировать реализацию по мере необходимости) и передать объект класса в качестве аргумента.

Также вы можете использовать отражение, передать методName как String в свой метод. и использовать отражение для вызова этого метода.

233787 просмотра

15 ответа

Репутация автора

Я ищу способ передать метод по ссылке. Я понимаю, что Java не передает методы в качестве параметров, однако я хотел бы получить альтернативу.

Мне сказали, что интерфейсы — это альтернатива передаче методов в качестве параметров, но я не понимаю, как интерфейс может действовать как метод по ссылке. Если я правильно понимаю, интерфейс — это просто абстрактный набор методов, которые не определены. Я не хочу отправлять интерфейс, который нужно определять каждый раз, потому что несколько разных методов могут вызывать один и тот же метод с одинаковыми параметрами.

То, что я хотел бы сделать, это что-то похожее на это:

Ответы (15)

24 плюса

2931 Репутация автора

Используйте java.lang.reflect.Method объект и позвоните invoke

202 плюса

20645 Репутация автора

Изменить : начиная с Java 8 лямбда-выражения являются хорошим решением, как указали другие ответы . Ответ ниже был написан для Java 7 и более ранних версий .

Читайте также:  Html input ввод только цифр

Редактировать: как отмечает Пит Киркхэм , есть еще один способ сделать это с помощью посетителя . Подход на основе посетителей немного более сложный — все ваши узлы должны быть осведомлены о посетителях с помощью acceptVisitor() метода, но если вам нужно пройти по более сложному графу объектов, стоит изучить его.

1 плюс

16319 Репутация автора

Используйте шаблон Observer (иногда его также называют шаблоном Listener):

new ComponentDelegate(). объявляет анонимный тип, реализующий интерфейс.

17 плюса

54795 Репутация автора

Сначала определите интерфейс с методом, который вы хотите передать в качестве параметра

Реализуйте класс с помощью метода

Это позволяет передавать cmd в качестве параметра и вызывать вызов метода, определенный в интерфейсе.

Автор: stacker Размещён: 02.02.2010 07:34

11 плюса

298 Репутация автора

В прошлый раз, когда я проверял, Java не может делать то, что вы хотите; Вы должны использовать «обходные пути», чтобы обойти такие ограничения. Насколько я понимаю, интерфейсы — это альтернатива, но не очень хорошая альтернатива. Возможно, тот, кто сказал вам, что имел в виду что-то вроде этого:

Который вы бы затем вызывать с:

1 плюс

7452 Репутация автора

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

12 плюса

29792 Репутация автора

Хотя это еще не действует для Java 7 и ниже, я считаю, что мы должны смотреть в будущее и, по крайней мере, признать изменения, которые появятся в новых версиях, таких как Java 8.

А именно, эта новая версия приносит лямбды и ссылки на методы в Java (вместе с новыми API , которые являются еще одним допустимым решением этой проблемы. Хотя им все еще требуется интерфейс, новые объекты не создаются, и дополнительные файлы классов не должны загрязнять выходные каталоги из-за различных обработка JVM.

Оба варианта (лямбда и ссылка на метод) требуют интерфейса, доступного для одного метода, чья сигнатура используется:

Имена методов не будут иметь значения с этого момента. Там, где принимается лямбда, также указывается метод. Например, чтобы использовать нашу подпись здесь:

Это простой вызов интерфейса до тех пор, пока не будет принята лямбда 1 :

Ссылки на метод похожи. Дано:

1 Это не считается лямбда, поскольку имеет побочные эффекты. Тем не менее, он иллюстрирует использование одного из них более простым для визуализации способом.

6 плюса

442 Репутация автора

Если вам не нужны эти методы для возврата чего-либо, вы можете заставить их возвращать объекты Runnable.

Тогда используйте это как:

Автор: Smig Размещён: 12.06.2014 01:40

54 плюса

6349 Репутация автора

В Java 8 теперь вы можете легче передавать метод, используя лямбда-выражения и ссылки на методы . Во-первых, немного предыстории: функциональный интерфейс — это интерфейс, который имеет один-единственный абстрактный метод, хотя он может содержать любое количество методов по умолчанию (новых в Java 8) и статических методов. Лямбда-выражение может быстро реализовать абстрактный метод без всего лишнего синтаксиса, необходимого, если вы не используете лямбда-выражение.

Синтаксис лямбда-выражений

Лямбда-выражение состоит из следующего:

Разделенный запятыми список формальных параметров, заключенный в скобки. Метод CheckPerson.test содержит один параметр p, который представляет экземпляр класса Person.

Примечание : вы можете опустить тип данных параметров в лямбда-выражении. Кроме того, вы можете опустить скобки, если есть только один параметр. Например, следующее лямбда-выражение также допустимо:

Тело, состоящее из одного выражения или блока операторов. В этом примере используется следующее выражение:

Если вы укажете одно выражение, тогда среда выполнения Java оценивает выражение и затем возвращает его значение. В качестве альтернативы вы можете использовать инструкцию возврата:

Оператор возврата не является выражением; в лямбда-выражении вы должны заключать выражения в фигурные скобки (<>). Однако вам не нужно заключать вызов метода void в фигурные скобки. Например, следующее является допустимым лямбда-выражением:

Обратите внимание, что лямбда-выражение очень похоже на объявление метода; Вы можете рассматривать лямбда-выражения как анонимные методы — методы без имени.

Вот как вы можете «передать метод» с помощью лямбда-выражения:

Класс C может быть сокращен еще немного, используя ссылки на методы, например, так:

плюса

6103 Репутация автора

Вот основной пример:

плюса

96 Репутация автора

Я не эксперт по Java, но я решаю вашу проблему следующим образом:

Я определяю параметр в моем специальном интерфейсе

Наконец, я реализую метод getSearchText при вызове метода initialize .

6 плюса

105 Репутация автора

Начиная с Java 8 есть Function интерфейс ( документы ), который имеет метод

Вы можете использовать его для передачи функций в качестве параметров другим функциям. T — тип ввода функции, R — тип возврата.

Читайте также:  Как вернуть старый яндекс после обновления

В вашем примере вам нужно передать функцию, которая принимает Component тип в качестве ввода и ничего не возвращает — Void . В этом случае Function не лучший выбор, так как здесь нет автобокса типа Void. Интерфейс, который вы ищете, называется Consumer ( docs ) с методом

Это будет выглядеть так:

И вы бы назвали это, используя ссылки на метод:

Предполагая, что вы определили методы changeColor () и changeSize () в одном классе.

Если ваш метод принимает более одного параметра, вы можете использовать BiFunction — T и U — типы входных параметров, а R — тип возвращаемых. Существует также BiConsumer (два аргумента, без возвращаемого типа). К сожалению, для 3 и более входных параметров, вы должны создать интерфейс самостоятельно. Например:

Автор: JakubM Размещён: 05.10.2017 02:26

плюса

14 Репутация автора

Я не думаю, что лямбды предназначены для этого . Java не является функциональным языком программирования и никогда не будет таким, мы не передаем методы в качестве параметров. При этом помните, что Java является объектно-ориентированной, и с учетом этого мы можем делать все, что захотим. Первая идея состоит в том, чтобы просто передать «объект, который содержит метод» в качестве параметра. Поэтому, когда вам нужно «передать» метод, просто передайте экземпляр этого класса. Обратите внимание, что когда вы определяете метод, вы должны добавить в качестве параметра экземпляр класса, который содержит метод. Это должно работать, но это не то, что мы хотим, потому что вы не можете переопределить метод, если у вас нет доступа к коду класса, а во многих случаях это невозможно; более того, Я думаю, что если кому-то нужно передать метод в качестве параметра, то это потому, что поведение метода должно быть динамичным. Я имею в виду, что программист, использующий ваши классы, должен иметь возможность выбирать, что должен возвращать метод, но не его тип. К счастью для нас, у Java есть красивое и простое решение: абстрактные классы. Вкратце, абстрактные классы используются, когда вы знаете «сигнатуру» метода », но не знаете его поведение . Вы можете обернуть имя и тип метода в абстрактный класс и передать экземпляр этого класса как параметр для метода . Подождите . разве это не то же самое, что и раньше? И можете ли вы иметь экземпляр абстрактного класса? Нет и нет . но также да . когда вы создаете абстрактный метод Вы также должны переопределить его в классе, который расширяет абстрактный класс и из-за Java ‘ Динамическое связывание Java будет всегда (если вы не объявите его статическим, частным и некоторыми другими вещами) использовать его переопределенную версию. Вот пример . Предположим, мы хотим применить функцию к массиву чисел: поэтому, если мы хотим возвести в квадрат, ввод-вывод должен выглядеть следующим образом [1,2,3,4, . ] -> [ 1,4,9,16, . ] (в функциональном языке программирования, таком как haskell, это легко сделать благодаря некоторым инструментам, таким как map, . ). Обратите внимание, что в квадрате чисел нет ничего особенного, мы можем применить любую функцию, какую захотим. Таким образом, код должен быть примерно таким [args], f -> [f (args)]. Вернемся к java => функция — это просто метод, поэтому нам нужна функция, которая применяет другую функцию к массиву. В двух словах, нам нужно передать метод в качестве параметра. Вот как бы я это сделал ==> частный и некоторые другие вещи) использовать переопределенную версию этого. Вот пример . Предположим, мы хотим применить функцию к массиву чисел: поэтому, если мы хотим возвести в квадрат, ввод-вывод должен выглядеть следующим образом [1,2,3,4, . ] -> [ 1,4,9,16, . ] (в функциональном языке программирования, таком как haskell, это легко сделать благодаря некоторым инструментам, таким как map, . ). Обратите внимание, что в квадрате чисел нет ничего особенного, мы можем применить любую функцию, какую захотим. Таким образом, код должен быть примерно таким [args], f -> [f (args)]. Вернемся к java => функция — это просто метод, поэтому нам нужна функция, которая применяет другую функцию к массиву. В двух словах, нам нужно передать метод в качестве параметра. Вот как бы я это сделал ==> частный и некоторые другие вещи) использовать переопределенную версию этого. Вот пример . Предположим, мы хотим применить функцию к массиву чисел: поэтому, если мы хотим возвести в квадрат, ввод-вывод должен выглядеть следующим образом [1,2,3,4, . ] -> [ 1,4,9,16, . ] (в функциональном языке программирования, таком как haskell, это легко сделать благодаря некоторым инструментам, таким как map, . ). Обратите внимание, что в квадрате чисел нет ничего особенного, мы можем применить любую функцию, какую захотим. Таким образом, код должен быть примерно таким [args], f -> [f (args)]. Вернемся к java => функция — это просто метод, поэтому нам нужна функция, которая применяет другую функцию к массиву. В двух словах, нам нужно передать метод в качестве параметра. Вот как бы я это сделал ==> Предположим, мы хотим применить функцию к массиву чисел: поэтому, если мы хотим возвести в квадрат, ввод-вывод должен выглядеть следующим образом [1,2,3,4, . ] -> [1,4,9,16 , . ] (в функциональном языке программирования, таком как haskell, это легко сделать благодаря таким инструментам, как map, . ). Обратите внимание, что в квадрате чисел нет ничего особенного, мы можем применить любую функцию, какую захотим. Таким образом, код должен быть примерно таким [args], f -> [f (args)]. Вернемся к java => функция — это просто метод, поэтому нам нужна функция, которая применяет другую функцию к массиву. В двух словах, нам нужно передать метод в качестве параметра. Вот как бы я это сделал ==> Предположим, мы хотим применить функцию к массиву чисел: поэтому, если мы хотим возвести в квадрат, ввод-вывод должен выглядеть следующим образом [1,2,3,4, . ] -> [1,4,9,16 , . ] (в функциональном языке программирования, таком как haskell, это легко сделать благодаря таким инструментам, как map, . ). Обратите внимание, что в квадрате чисел нет ничего особенного, мы можем применить любую функцию, какую захотим. Таким образом, код должен быть примерно таким [args], f -> [f (args)]. Вернемся к java => функция — это просто метод, поэтому нам нужна функция, которая применяет другую функцию к массиву. В двух словах, нам нужно передать метод в качестве параметра. Вот как бы я это сделал ==> ). Обратите внимание, что в квадрате чисел нет ничего особенного, мы можем применить любую функцию, какую захотим. Таким образом, код должен быть примерно таким [args], f -> [f (args)]. Вернемся к java => функция — это просто метод, поэтому нам нужна функция, которая применяет другую функцию к массиву. В двух словах, нам нужно передать метод в качестве параметра. Вот как бы я это сделал ==> ). Обратите внимание, что в квадрате чисел нет ничего особенного, мы можем применить любую функцию, какую захотим. Таким образом, код должен быть примерно таким [args], f -> [f (args)]. Вернемся к java => функция — это просто метод, поэтому нам нужна функция, которая применяет другую функцию к массиву. В двух словах, нам нужно передать метод в качестве параметра. Вот как бы я это сделал ==>

Читайте также:  Фрегат что это такое

1) Определите класс обертки и метод

2) ОПРЕДЕЛИТЬ КЛАСС С МЕТОДОМ APPLY_TO_ARRAY

3) СОЗДАЙТЕ КЛАСС ИСПЫТАТЕЛЯ И ИМЕЙТЕ НЕКОТОРОЕ УДОВОЛЬСТВИЕ

Обратите внимание, что нам нужно передать объект типа Function, и, поскольку Testclass расширяет класс Function, мы можем его использовать, приведение происходит автоматически.

плюса

843 Репутация автора

Я не нашел достаточно четкого примера для меня, как использовать java.util.function.Function для простого метода функцию параметра. Вот простой пример:

В основном у вас есть Foo объект с конструктором по умолчанию. Объект, method который будет вызываться как параметр из parametrisedMethod типа Function .

  • Function означает, что функция принимает в String качестве параметра и возвращает a Foo .
  • Foo::Method Соответствуют лямбда как x -> Foo.method(x);
  • parametrisedMethod(Foo::method) можно рассматривать как x -> parametrisedMethod(Foo.method(x))
  • В .apply("from a method") основном делать parametrisedMethod(Foo.method("from a method"))

Который затем вернется в выводе:

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

Автор: Sylhare Размещён: 09.11.2018 04:37

плюса

580 Репутация автора

Я не нашел здесь никакого решения, показывающего, как передать метод с привязанными к нему параметрами в качестве параметра метода. Ниже приведен пример того, как вы можете передать метод со значениями параметров, уже привязанными к нему.

  1. Шаг 1: Создайте два интерфейса, один с типом возврата, другой без. У Java есть подобные интерфейсы, но они мало практического использования, потому что они не поддерживают исключение.
  1. Пример того, как мы используем оба интерфейса для переноса вызова метода в транзакции. Обратите внимание, что мы передаем метод с фактическими параметрами.

Другой пример показывает, как передать метод, который на самом деле возвращает что-то