Как использовать ссылку метода на статический импорт?
При использовании функций отображения в java я могу сделать следующее:
import com.example.MyClass;
someStream.map(MyClass::myStaticMethod)
но в моем проекте мы иногда используем статический импорт, как я могу ссылаться на myStaticMethod, когда импорт статичен?
Я бы подумал, что это сработает, но это не так:
import static com.example.MyClass.myStaticMethod;
someStream.map(myStaticMethod); //does not compile
Почему это не работает? Я "застрял" с использованием первого примера или других решений.
Ответы
Ответ 1
Посмотрите на соответствующую часть спецификации языка Java, 15.13. Выражения для ссылки метода.
В нем перечислены следующие способы ссылки на метод создания:
MethodReference:
ExpressionName :: [TypeArguments] Identifier
ReferenceType :: [TypeArguments] Identifier
Primary :: [TypeArguments] Identifier
super :: [TypeArguments] Identifier
TypeName . super :: [TypeArguments] Identifier
ClassType :: [TypeArguments] new
ArrayType :: new
Обратите внимание, что все они содержат токен ::
.
Поскольку аргумент someStream.map(myStaticMethod)
не включает ::
, это не действительная ссылка метода.
Это говорит о необходимости импортировать MyClass
(возможно, в дополнение к статическому импорту, если это предпочтение) и ссылаться на метод как MyClass::myStaticMethod
.
Ответ 2
Ну, это не компиляция, потому что JLS так говорит. Но это невозможно даже скомпилировать, поскольку это будет обычный вызов метода, а не ссылка на метод, которая определена ТОЛЬКО с использованием нотации ::
, будь то статический или экземпляр, используемый для.
Это интересный аспект, который вы не можете решить - может быть в данный момент. Не существует языковой поддержки для определения чего-то вроде:
MethodRef <Class, Method> ref = ...
И позже используйте так, как хотите. Но я даже не думаю, что это было бы возможно, потому что вам также необходимо было бы определить типы параметров и тип возвращаемого типа, потому что это необходимо для того, чтобы увидеть, совпадает ли оно с несколькими другими местами. Подобно Predicate<String>
и Function<String, Boolean>
, которые потенциально могут применяться к тому же method reference
.
Ответ 3
Наличие статического импорта метода не влияет на способ определения ссылки на метод.
Итак, если вы хотите, чтобы он работал, он должен выглядеть точно так же, как перед введением статического импорта:
MyClass::myStaticMethod
Ответ 4
При статическом импорте метода вы можете звонить, но не ссылаться на него. Для stream(). Map() ему нужна ссылка на функцию, чтобы она могла вызвать ее для каждой записи.