本文最后更新于 941 天前,其中的信息可能已经有所发展或是发生改变。
四大函数式接口
消费型接口
@FunctionalInterface
public interface Consumer {
void accept(T t);
}
供给型接口
@FunctionalInterface
public interface Supplier {
T get();
}
断定型接口
@FunctionalInterface
public interface Predicate {
boolean test(T t);
}
函数型接口
@FunctionalInterface
public interface Function {
R apply(T t);
}
SerializedLambda
在java 8中,如果函数式接口继承了Serializable,且被lambda表达式实现时,编译后的实现类会有一个私有”writeReplace”方法,该方法返回一个SerializedLambda对象。通过SerializedLambda类,我们可以获得函数式接口及其实现类等各种信息。
@FunctionalInterface
public interface SFunction extends Function, Serializable {
}
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.function.Function;
public class LambdaUtils {
/**
* 获取实现lambda函数型接口方法返回的Field,如 User::getName -> name
*/
public static Field convertToField(Function column) {
String entityName = null;
String methodName = null;
try {
Method method = column.getClass().getDeclaredMethod("writeReplace");
method.setAccessible(true);
SerializedLambda serializedLambda = (SerializedLambda) method.invoke(column);
//获取实现方法所在类的全限定名,用"/"连接的字符串
entityName = serializedLambda.getImplClass().replace("/", ".");
//获取实现方法的名称
methodName = serializedLambda.getImplMethodName();
String fieldName = captureName(methodName);
return Class.forName(entityName).getDeclaredField(fieldName);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(entityName + " method: '" + methodName + "' must be getXxx.");
}
}
/**
* 获取getter或setter方法的字段名,如 getName -> name
*/
public static String captureName(String name) {
if (!name.startsWith("get") && !name.startsWith("set")) {
throw new IllegalStateException("Error parsing property name '" + name + "'. Didn't start with 'get' or 'set'.");
}
char[] chars = Arrays.copyOfRange(name.toCharArray(), 3, name.length());
if (chars.length >= 1 && chars[0] >= 65 && chars[0] <= 90) {
chars[0] += 32;
}
return String.valueOf(chars);
}
}