Java7: 什么相当于在函数调用中指定方法引用
Java7: What is some equivalent to specifing method references in a function call
我想编写一个方法,在适当的对象上调用指定的方法。
需要注意的是,我想在不更改调用方法的 classes(例如实现接口)的情况下执行此操作。
我在 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 中实现类似的功能?唯一的限制是 class A 和 B 不能改变。
如果类型未对编译器隐藏,则加分。
在 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);
}
}
在 Java7 中,具有类似方法引用的等效代码如下:
首先,我们定义一个接口供我们参考(与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()
}
});
}
}
创建或选择一个 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
}
}
我想编写一个方法,在适当的对象上调用指定的方法。
需要注意的是,我想在不更改调用方法的 classes(例如实现接口)的情况下执行此操作。
我在 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 中实现类似的功能?唯一的限制是 class A 和 B 不能改变。
如果类型未对编译器隐藏,则加分。
在 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);
}
}
在 Java7 中,具有类似方法引用的等效代码如下: 首先,我们定义一个接口供我们参考(与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()
}
});
}
}
创建或选择一个 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
}
}