optimization - Java: How to check for null pointers efficiently -
there patterns checking whether parameter method has been given null
value.
first, classic one. common in self-made code , obvious understand.
public void method1(string arg) { if (arg == null) { throw new nullpointerexception("arg"); } }
second, can use existing framework. code looks little nicer because occupies single line. downside potentially calls method, might make code run little slower, depending on compiler.
public void method2(string arg) { assert.notnull(arg, "arg"); }
third, can try call method without side effects on object. may odd @ first, has fewer tokens above versions.
public void method3(string arg) { arg.getclass(); }
i haven't seen third pattern in wide use, , feels if had invented myself. shortness, , because compiler has chance of optimizing away or converting single machine instruction. compile code line number information, if nullpointerexception
thrown, can trace exact variable, since have 1 such check per line.
which check prefer, , why?
approach #3: arg.getclass();
clever, unless idiom see widespread adoption, i'd prefer clearer, more verbose methods opposed saving few characters. i'm "write once, read many" kind of programmer.
the other approaches self-documenting: there's log message can use clarify happened - log message use when reading code , @ run-time. arg.getclass()
, stands, not self-documenting. use comment @ least o clarify reviewers of code:
arg.getclass(); // null check
but still don't chance put specific message in runtime can other methods.
approach #1 vs #2 (null-check+npe/iae vs assert): try follow guidelines this:
http://data.opengeo.org/geot-290810-1755-708.pdf
use
assert
check parameters on private methods
assert param > 0;
use null check +
illegalargumentexception
check parameters on public methods
if (param == null) throw new illegalargumentexception("param cannot null");
use null check + nullpointerexception needed
if (getchild() == null) throw new nullpointerexception("node must have children");
however, since question may catching potential null
issues efficiently, have mention preferred method dealing null
using static analysis, e.g. type annotations (e.g. @nonnull
) la jsr-305. favorite tool checking them is:
the checker framework:
custom pluggable types java
https://checkerframework.org/manual/#checker-guarantees
if project (e.g. not library public api) , if can use checker framework throughout:
i can document intention more in api (e.g. parameter may not null (the default), 1 may null (
@nullable
; method may return null; etc). annotation right @ declaration, rather further away in javadoc, more maintained.static analysis more efficient runtime check
static analysis flag potential logic flaws in advance (e.g. tried pass variable may null method accepts non-null parameter) rather depending on issue occurring @ runtime.
one other bonus tool lets me put annotations in comment (e.g. `/@nullable/), library code can compatible type-annotated projects , non-type-annotated projects (not have of these).
in case link goes dead again, here's section geotools developer guide:
http://data.opengeo.org/geot-290810-1755-708.pdf
5.1.7 use of assertions, illegalargumentexception , npe
the java language has couple of years made assert keyword available; keyword can used perform debug checks. while there several uses of facility, common 1 check method parameters on private (not public) methods. other uses post-conditions , invariants.
reference: programming assertions
pre-conditions (like argument checks in private methods) typically easy targets assertions. post-conditions , invariants sometime less straighforward more valuable, since non-trivial conditions have more risks broken.
- example 1: after map projection in referencing module, assertion performs inverse map projection , checks result original point (post-condition).
- example 2: in directposition.equals(object) implementations, if result true, assertion ensures hashcode() identical required object contract.
use assert check parameters on private methods
private double scale( int scaledenominator ){ assert scaledenominator > 0; return 1 / (double) scaledenominator; }
you can enable assertions following command line parameter:
java -ea myapp
you can turn geotools assertions following command line parameter:
java -ea:org.geotools myapp
you can disable assertions specific package shown here:
java -ea:org.geotools -da:org.geotools.referencing myapp
use illegalargumentexceptions check parameters on public methods
the use of asserts on public methods strictly discouraged; because mistake being reported has been made in client code - honest , tell them front illegalargumentexception when have screwed up.
public double toscale( int scaledenominator ){ if( scaledenominator > 0 ){ throw new illegalargumentexception( "scaledenominator must greater 0"); } return 1 / (double) scaledenominator; }
use nullpointerexception needed
if possible perform own null checks; throwing illegalargumentexception or nullpointerexception detailed information has gone wrong.
public double toscale( integer scaledenominator ){ if( scaledenominator == null ){ throw new nullpointerexception( "scaledenominator must provided"); } if( scaledenominator > 0 ){ throw new illegalargumentexception( "scaledenominator must greater 0"); } return 1 / (double) scaledenominator; }
Comments
Post a Comment