Java7:在函数调用中指定方法引用等同于什么

时间:2017-01-27 15:08:45

标签: java java-7 method-reference

我想编写一个方法,在适当的对象上调用指定的方法 需要注意的是,我想在不改变调用方法的类(例如实现接口)的情况下这样做。

我在C中的函数指针中找到了我想要的东西,但是Java 7还没有找到。

这里有一些伪代码:

public class A {
    ... constructor ...

    public String aToString(){
        return "A";
    }
}

public class B {
    ... constructor ...

    public String bToString(){
        return "B";
    }
}
/* T::<String>mymethod stands for "Method with identifier 'mymethod'
 * in Class T with return type String"
 */
public class ServiceClass {
    public static void genericToString(Collection<T> c, 
                                       MethodPointer T::<String>mymethod){
        for(int i=0,i<c.length,i++) {
            System.out.println(c.get(i).mymethod());

        }
    }

    public static void main(){
        ArrayList<A> listA = new ArrayList<A>();
        listA.add(new A());
        ServiceClass.genericToStringOutput(listA, A::<String>aToString);

        ArrayList<B> listB = new ArrayList<B>();
        listB.add(new B());
        ServiceClass.genericToStringOutput(listB, B::<String>bToString);
    }
}

有没有办法在Java 7中实现这样的功能?唯一的限制是A类和B类可能不会改变。

如果未从编译器中隐藏类型,则为奖励积分。

3 个答案:

答案 0 :(得分:4)

制作或选择Function界面并将其传递给:

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

class A {
  public String aToString() {
    return "A";
  }
}

class B {
  public String bToString() {
    return "B";
  }
}

interface Function<IN, OUT> {
  OUT apply(IN input);//see guava for a prefab version of this
}

class ServiceClass {
  public static <T> void genericToString(Collection<T> c, Function<T, String> converter) {
    for (final T element : c) {
      System.out.println(converter.apply(element));
    }
  }

  public static void main() {
    List<A> listA = new ArrayList<>();
    listA.add(new A());
    ServiceClass.genericToString(listA, new Function<A, String>() {//the java 7 way
      @Override
      public String apply(final A input) {
        return input.aToString();
      }
    });

    List<B> listB = new ArrayList<>();
    listB.add(new B());
    ServiceClass.genericToString(listB, B::bToString);//the java 8 way
  }
}

答案 1 :(得分:1)

在Java 7中,具有类似方法引用的等效代码如下: 首先,我们为我们的参考定义了一个接口(与Java 8相比没有什么不同):

public interface MethodPointer<T> {
  String invoke(T arg);
}

然后我们使用它:

public class ServiceClass {
public static void genericToString(Collection<T> c, 
                                   MethodPointer<T> mymethod) {
    for(int i=0,i<c.length,i++) {
        System.out.println(mymethod.invoke(c.get(i)));
    }
}

public static void main() {
    ArrayList<A> listA = new ArrayList<A>();
    listA.add(new A());
    ServiceClass.genericToStringOutput(listA, new MethodPointer<A>() {
      @Override public String invoke(A arg) {
        return arg.toString();
      }
    });

    ArrayList<B> listB = new ArrayList<B>();
    listB.add(new B());
    ServiceClass.genericToStringOutput(listB, new MethodPointer<B>() {
      @Override public String invoke(B arg) {
        return arg.toDetailedString() // <- note that it's not just toString()
      }
    });
}

}

答案 2 :(得分:-2)

在Java 7中,您正在寻找类似

的内容
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;

public class ServiceClass<T> {

    public void genericToString(Collection<T> c, Method m)
        throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
        for(T e : c) {
            System.out.println(m.invoke(e));
        }
    }

    public static void main(){
        Method m;
        ArrayList<A> listA = new ArrayList<A>();
        listA.add(new A());
        m = new A().getClass().getMethod("aToString", new Class[]{});
        ServiceClass.genericToStringOutput(listA, m);

        ArrayList<B> listB = new ArrayList<B>();
        listB.add(new B());
        m = new B().getClass().getMethod("bToString", new Class[]{});
        ServiceClass.genericToStringOutput(listB, m);
    }
}