Arm*_*ius 12
Well, a lambda expression is just an instance of a special anonymous class that only has one method. Anonymous classes can "capture" variables that are in the surrounding scope. If your definition of a stateful class is one that carries mutable stuff in its fields (otherwise it's pretty much just a constant), then you're in luck, because that's how capture seems to be implemented. Here is a little experiment :
import java.lang.reflect.Field;
import java.util.function.Function;
public class Test {
public static void main(String[] args) {
final StringBuilder captured = new StringBuilder("foo");
final String inlined = "bar";
Function<String, String> lambda = x -> {
captured.append(x);
captured.append(inlined);
return captured.toString();
};
for (Field field : lambda.getClass().getDeclaredFields())
System.out.println(field);
}
}
Run Code Online (Sandbox Code Playgroud)
The output looks something like this :
private final java.lang.StringBuilder Test$$Lambda$1/424058530.arg$1
Run Code Online (Sandbox Code Playgroud)
The StringBuilder reference got turned into a field of the anonymous lambda class (and the final String inlined constant was inlined for efficiency, but that's beside the point). So this function should do in most cases :
public static boolean hasState(Function<?,?> lambda) {
return lambda.getClass().getDeclaredFields().length > 0;
}
Run Code Online (Sandbox Code Playgroud)
EDIT : as pointed out by @Federico this is implementation-specific behavior and might not work on some exotic environments or future versions of the Oracle / OpenJDK JVM.
这是一个简单而愚蠢的想法。只需检查您的 lambda 是否有字段即可。
例如,考虑以下有状态 lambda。
List<Integer> serialStorage = new ArrayList<>();
Function<? super Integer, ? extends Integer> statefulLambda =
e -> { serialStorage.add(e); return e; };
Run Code Online (Sandbox Code Playgroud)
这有一个明显引用的statefulLambda私有最终内部字段。所以arg$1serialStorage
statefulLambda.getClass().getDeclaredFields().length > 0
Run Code Online (Sandbox Code Playgroud)
可以用作 lambda 是有状态的指示器。
但是我不知道这通常是否有效。
| 归档时间: |
|
| 查看次数: |
1604 次 |
| 最近记录: |