-
Enhancement
-
Resolution: Fixed
-
P3
-
9
-
b54
-
Not verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8085355 | emb-9 | Maurizio Cimadamore | P3 | Resolved | Fixed | team |
A langtools coding rule test fails with code like as the one below:
Assert.checkNonNull(name, "null name for tag " + tag);
While I might be sympathetic about the end goal, I think the current check is overly restrictive, as there are no good alternatives to such code.
Alternatively, we could add lazy evaluation with the following overload:
checkNonNull(Object o, String s) //to be used for plain string messages - no concatenation, no method calls - just string constants
checkNonNull(Object o, Supplier<String>) //to be used in all other cases
In this way the code above would become:
Assert.checkNonNull(name, () -> "null name for tag " + tag);
Some JMH benchmarks done in order to evaluate the lambda strategy:
1) Assert.checkNonNull with simple (String constant) argument
2) Assert.checkNonNull with complex argument (the resulting string is generated in a for each loop concatenating lots of strings)
3) Assert.checkNonNull where the above complex argument is 'hidden' inside a lambda (for lazy evaluation)
Here are the results:
Benchmark Mode Cnt Score Error Units
MyBenchmark.testCheckComplexArg thrpt 200 76.188 ± 0.434 ops/s
MyBenchmark.testCheckSimpleArg thrpt 200 1288408445.576 ± 36036213.893 ops/s
MyBenchmark.testChecklambdaWithComplexArg thrpt 200 1473275042.384 ± 25887725.576 ops/s
Hence, the lambda version gives rougly same numbers as the plain string version.
As part of the work the checker rule will be made stricter so that the only thing you can pass to a String accepting method is one of the following:
* String constant (this would probably include stuff like "Hello" + "World!" (and friends) - which is converted by javac into a single string
* reference to String field
* reference to String local variable
All other cases will be banned and a message will prompt the developer to use the lazy (lambdified) version of the assertion check.
Assert.checkNonNull(name, "null name for tag " + tag);
While I might be sympathetic about the end goal, I think the current check is overly restrictive, as there are no good alternatives to such code.
Alternatively, we could add lazy evaluation with the following overload:
checkNonNull(Object o, String s) //to be used for plain string messages - no concatenation, no method calls - just string constants
checkNonNull(Object o, Supplier<String>) //to be used in all other cases
In this way the code above would become:
Assert.checkNonNull(name, () -> "null name for tag " + tag);
Some JMH benchmarks done in order to evaluate the lambda strategy:
1) Assert.checkNonNull with simple (String constant) argument
2) Assert.checkNonNull with complex argument (the resulting string is generated in a for each loop concatenating lots of strings)
3) Assert.checkNonNull where the above complex argument is 'hidden' inside a lambda (for lazy evaluation)
Here are the results:
Benchmark Mode Cnt Score Error Units
MyBenchmark.testCheckComplexArg thrpt 200 76.188 ± 0.434 ops/s
MyBenchmark.testCheckSimpleArg thrpt 200 1288408445.576 ± 36036213.893 ops/s
MyBenchmark.testChecklambdaWithComplexArg thrpt 200 1473275042.384 ± 25887725.576 ops/s
Hence, the lambda version gives rougly same numbers as the plain string version.
As part of the work the checker rule will be made stricter so that the only thing you can pass to a String accepting method is one of the following:
* String constant (this would probably include stuff like "Hello" + "World!" (and friends) - which is converted by javac into a single string
* reference to String field
* reference to String local variable
All other cases will be banned and a message will prompt the developer to use the lazy (lambdified) version of the assertion check.
- backported by
-
JDK-8085355 Add lambda-based lazy eval versions of Assert.check methods
-
- Resolved
-