У меня есть строфа кода, которая неоднократно используется. Вот два примера:Java - как передать метод в качестве параметра?
public java.sql.Struct createStruct(String typeName, Object[] attributes) {
String searchPath = getSearchPath();
String name = setSearchPathToSchema(typeName);
Struct ret = delegate().createStruct(name.toLowerCase(), attributes);
setSearchPath(searchPath);
return ret;
}
public java.sql.Array createArray(String typeName, Object[] elements) {
String searchPath = getSearchPath();
String name = setSearchPathToSchema(typeName);
Array ret = delegate().createArray(name.toLowerCase(), elements);
setSearchPath(searchPath);
return ret;
}
Вы можете видеть, что эти два метода имеют общий вид:
public <T> createXXX(String typeName, Object[] objects) {
String searchPath = getSearchPath();
String name = setSearchPathToSchema(typeName);
T ret = delegate().createXXX(name.toLowerCase(), objects);
setSearchPath(searchPath);
return ret;
}
Где T
является типом возвращаемого некоторого множества функций createXXX
, которые имеют общую подпись, но разные возвращаемый тип.
Я уверен, что сделаю это в Javascript, F #, C#, Scala или любом другом языке.
Я просто не могу оборачивать голову тем, как это сделать на Java, безопасным образом, что позволяет мне вызвать каждый метод createXXX
, так что установка и срыв могут произойти в одном блоке кода , а не посыпать по всему методу обертки.
Я знаю, что могу использовать отражение, но я ищу способ сделать это, используя lambdas, если это возможно, или какая-либо структура имеет наибольший смысл в Java.
Что-то вроде этого, где метод будет называться передается в качестве третьего параметра (я знаю, что этот код полностью уродливы в Java):
public Struct createStruct(String typeName, Object[] attributes) {
return createTypeWithCorrectSearchPath<>(
typeName,
attributes,
delegate().createStruct
);
}
public Struct createArray(String typeName, Object[] elements) {
return createTypeWithCorrectSearchPath<>(
typeName,
elements,
delegate().createArray
);
}
private <T> T createTypeWithCorrectSearchPath(
String typeName,
Object[] objects,
[SOME-METHOD-HERE]) {
String searchPath = getSearchPath();
String name = setSearchPathToSchema(typeName);
T ret = [SOME-METHOD-HERE](name, objects);
setSearchPath(searchPath);
return ret;
}
Я читал, видимо, дублирующие вопросы:
- How do I pass a method as a parameter in Java 8?
- How do I pass method as a parameter in Java?
- Java Pass Method as Parameter
Как и некоторые вопросы о ссылках метод с дженериков:
По какой причине он не гелеобразования для меня, поэтому я рискую с просьбой вопрос, который сразу же будет отмечен как дубликат в надежде, что кто-то пожалеет и поможет мне ...
UPDATE 2015-02-06
Хотя оба Louis Wasserman и Neuron дали в основном один и тот же ответ, он был Луи, что более педантично предложил модель, которая работала лучше для меня ... с явным примером того, как передать метод ссылка.
Вот что в конечном итоге работает для меня:
interface SearchPathCreator<T> {
T create(String typeName, Object[] objects) throws SQLException;
}
private <T> T createTypeWithCorrectSearchPath(
String typeName,
Object[] objects,
SearchPathCreator<?> creator) throws SQLException {
String searchPath = getSearchPath();
String name = setSearchPathToSchema(typeName);
//noinspection unchecked
T ret = (T) creator.create(name.toLowerCase(), objects);
setSearchPath(searchPath);
return ret;
}
, который называется так же, как Луис предложил:
public Struct createStruct(
String typeName,
Object[] attributes) throws SQLException {
return createTypeWithCorrectSearchPath(
typeName,
attributes,
delegate()::createStruct
);
}
@ajb Вопрос OP, казалось, указывал на передачу в делегате() :: createStruct' как прекрасно, под частью «Что-то вроде этого». Я основывал свой ответ на этом предположении. Если бы у ОП не было такого примера, я бы переместил «Делегировать» в метод интерфейса. –
Да, я просто подумал об этом ... – ajb
Этот ответ дал мне самый дальний. Когда я использую этот шаблон дословно, ссылка метода 'delegate() :: createStruct' в' createTypeWithCorrectSearchPath' показывает 'Bad возвращаемый тип в ссылке метода: не может преобразовать' java.sql.Struct' в 'T'. Я обновил свой вопрос со структурой, которая закончилась работой. – rbellamy