Is there a function which accepts a reference to a lambda expression and returns a boolean saying whether the lambda expression is stateless or not? How can the statefulness of a lambda expression be determined?
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
I would argue that it is not possible to write a function that can determine if a lambda is stateless or not:
Looking for example at the
filter
method of the Stream API, the javadoc states that the parameter must be "a [...] stateless predicate" and also links to the API's definition of stateless.If there was a way to determine if the parameter of the
filter
(or any other) method was stateless or not, the Stream class would have included the possibility to throw an IllegalArgumentException in case the parameter was a stateful lambda. As this has not been implemented and only a warning was added to the javadocs, one can conclude that there is no way write a function that can determine if a lambda lambda is stateless.Edit (after reading the comments from Eric): There are plenty of situations where an implementation team makes implementation choices to not implement a particular feature; we usually cannot conclude from those choices that the feature is impossible for someone else to implement. In this special case, I believe its implausible that the Java 8 designers would not have found or done it if there was a (computational cheap) solution.
No, it is not generally possible. The suggested approach of checking whether the lambda belongs to a class with a field is the next best thing, but having a field does not equal having a state.
It is possible to prove statefulness by finding two input sequence for which a given input combination returns a different result. However, it is not possible to prove that such a input sequence does not exist (any input sequence might produce a different result if prepended by another invocation).
(Even if you check the values of fields found via reflection, those might change without influencing the lambda's result, therefore not really making it stateful).
Here's a short compilable example showing both false positive and negatives, disproving the notion:
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 :
The output looks something like this :
The
StringBuilder
reference got turned into a field of the anonymous lambda class (and thefinal String inlined
constant was inlined for efficiency, but that's beside the point). So this function should do in most cases :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.
Here's a simple and stupid idea. Just check if your lambda has fields.
For instance, consider the following stateful lambda.
This
statefulLambda
has a private final internal fieldarg$1
which obviously referencesserialStorage
. Socould be used as indicator that lambda is stateful.
However I have no idea if this will generally work.