【发布时间】:2016-02-06 19:54:29
【问题描述】:
我有一段重复使用的代码。这里有两个例子:
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
还有一些关于方法引用与泛型的问题:
无论出于何种原因,它对我来说都不是很好,所以我冒着风险提出一个会立即被标记为重复的问题,希望有人会同情并帮助我......
2015-02-06 更新
虽然Louis Wasserman 和Neuron 给出了基本相同的答案,但Louis 更迂腐地提供了一种最适合我的模式......并提供了一个关于如何传递方法参考的明确示例。
这就是最终对我有用的东西:
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;
}
就像 Louis 建议的那样:
public Struct createStruct(
String typeName,
Object[] attributes) throws SQLException {
return createTypeWithCorrectSearchPath(
typeName,
attributes,
delegate()::createStruct
);
}
【问题讨论】: