Java - 如何将方法作为参数传递?

rbe*_*amy 3 java lambda

我有一个重复使用的代码节.这是两个例子:

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;
}
Run Code Online (Sandbox Code Playgroud)

您可以看到这两种方法具有一般形式:

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;
}
Run Code Online (Sandbox Code Playgroud)

具有共同签名但返回类型不同T的某些函数集的返回类型在哪里createXXX.

我非常确定如何在Javascript,F#,C#,Scala或任何其他语言中执行此操作.

我似乎无法在Java中以类型安全的方式解决如何在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;
}
Run Code Online (Sandbox Code Playgroud)

我已经阅读了明显重复的问题:

  1. 如何在Java 8中将方法作为参数传递?
  2. 如何在Java中将方法作为参数传递?
  3. Java Pass方法作为参数

以及有关泛型的方法引用的一些问题:

  1. 带有泛型类型的Java 8方法引用
  2. Java方法引用具有泛型参数的方法

无论出于何种原因,这对我来说都没有凝胶化,所以我冒着问一个问题会立即被标记为重复,希望有人会怜惜并帮助我...

更新2015-02-06

虽然Louis WassermanNeuron给出了基本相同的答案,但路易斯更迂腐地提供了一种最适合我的模式......以及如何传递方法参考的明确示例.

以下是最终为我工作的内容:

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;
}
Run Code Online (Sandbox Code Playgroud)

就像路易斯建议的那样:

public Struct createStruct(
                String typeName,
                Object[] attributes) throws SQLException {
    return createTypeWithCorrectSearchPath(
             typeName,
             attributes,
             delegate()::createStruct
    );
}
Run Code Online (Sandbox Code Playgroud)

Lou*_*man 5

interface MyMethodType<T> {
  T method(String name, Object[] objects);
}


private <T> T createTypeWithCorrectSearchPath(
            String typeName, 
            Object[] objects, 
            MyMethodType<T> impl) {
    String searchPath = getSearchPath();
    String name = setSearchPathToSchema(typeName);
    T ret = impl.method(name, objects);
    setSearchPath(searchPath);
    return ret;
}

createTypeWithCorrectSearchPath(typeName, objects, delegate()::createStruct);
Run Code Online (Sandbox Code Playgroud)

关键的一点是a)创建自己的接口类型,虽然我想你可以使用BiFunction<String, Object[]>,b)使用方法引用::.

  • 这似乎......非常奇怪.我似乎更有可能想要一个显式类型参数,而不是你似乎最终得到的未经检查的强制转换. (2认同)