How to track a method parameter? - java

I have been trying to find the exact term for "tracking a method's parameter" for Java programming language and I generally found "taint analysis", but still not sure if I am on the right path.
What I want is, to keep track of a method's parameter and see which part of the method (in scope) does the parameter effect. For example, if a parameter is assigned to another variable, I also want to keep of track of the assigned variable as well. By mentioning "parts", it could be lines of code, statement or branch of a control flow graph.
I also checked for tools and came across with Checker Framework and Findbugs, however it seems that they don't quite satisfy the needs that I want or I couldn't manage to make them work for my needs.
Please tell if "taint analysis" is the right term that I am looking for. Also, any other tool suggestions are welcome.
There is an edited code below from Checker Framework Live Demo. What I expect is, inside processRequest() when the variable String input is Tainted, I expect to get a warning or an error for all of the lines inside executeQuery() method. Because a tainted variable is passed to it's parameter.
import org.checkerframework.checker.tainting.qual.*;
public class TaintingExampleWithWarnings {
String getUserInput() {
return "taintedStr";
}
void processRequest() {
#Tainted String input = getUserInput();
executeQuery(input); //error: pass tainted string to executeQeury()
}
public void executeQuery(#Untainted String input) {
// Do some SQL Query
String token = input + " Hello World";
String tokens[] = token.split(" ");
for(int i=0; i<tokens.length; i++)
{
System.out.println((i+1)+"String: "+tokens[i])
}
}
/* To eliminate warning in line 10, replace line 10 by
* executeQuery(validate(input)); */
/*#Untainted*/ public String validate(String userInput) {
// Do some validation here
#SuppressWarnings("tainting")
#Untainted String result = userInput;
return result;
}
}

The Tainting Checker of the Checker Framework issues a warning on exactly the defective line of your code:
% javac -g TaintingExampleWithWarnings.java -processor tainting
TaintingExampleWithWarnings.java:10: error: [argument.type.incompatible] incompatible types in argument.
executeQuery(input); //error: pass tainted string to executeQeury()
^
found : #Tainted String
required: #Untainted String
1 error
This pinpoints the defect and indicates exactly what you need to fix in your program.
I expect to get a warning or an error for all of the lines inside
executeQuery() method
The implementation of executeQuery() is correct; it's the use of executeQuery() that is problematic.
(Background: A modular analysis is one that works one method at a time. A modular analysis relies on specifications of methods.)
Type-checking is an example of a modular analysis. Its specifications are user-written annotations on formal parameters.
When type-checking the body of executeQuery(), the type-checker assumes
that the formal parameter declarations are correct.
When type-checking a call to executeQuery(), the type-checker verifies that the arguments are legal.
If there is even one type-checking error somewhere in your program, then
your program might behave unsafely (possibly at some other location).
If you want to know all the possible places that taint could flow to in your program, then you need to use a non-modular, whole-program analysis. Furthermore, the whole-program analysis would need to ignore every user-written annotation in the program. Such an analysis is possible to do and is a reasonable desire, but it is not addressed by the tools you mentioned in your question.

Related

Use variable name semantically in Java

I'm currently trying to set some parameters from an external system. I have a request with named parameters, and in order to properly set the variables, I'm using annotated method arguments on my service calls. A simplified example might be
public Response loginAttempt(#MyParam("username") String username, #MyParam("password") String password) {
// login logic here
}
Clearly, annotating each argument name is annoying and duplicative (although, it does have the minor advantage of allowing me to change the name over different versions of the API, that's beside the point.)
It would be very, very handy if I was able to, in my reflective portion, to simply reference the name of the argument. Where now, I get the arguments and their annotations, note their order, make an array of that order, and run with it.
I know in previous version of Java this simply cannot be done. I also know Java is releasing versions faster than ever before, with newer and more modern features than ever before. Unfortunately, the signal to noise ratio with 15 year old information is too just not high enough to get a definitive answer. Is this something that can be done with modern Java?
Since Java 8 if you compile your code with javac -parameters option and the method parameters will be retained, however there are drawbacks. The problem is primarily the class file size, take a look at Obtaining Names of Method Parameters docs.
You can use java.lang.reflect.Parameter.getName() to get the method parameter name:
Method m = getClass().getMethods()[0];
System.out.println(m.getName()); // loginAttempt
Parameter[] parameters = m.getParameters();
for (Parameter parameter : parameters) {
System.out.print(parameter.getName() + " "); // username password
}

Why is the Java compiler giving the incoherent ".class expected" compile error?

If I have a piece of code like this:
public class ABC {
public static void main(String[] args) {
if (true)
int a = 0;
}
}
When I compile it, Java compiler produces an error
.class expected.
I know that when we don't use braces, we can use only one statement after if.
And I also know that I will not be able to use the int variable a, because as soon as the ; is encountered, the program comes out of if, and the variable a loses it's scope.
I am not surprised that this code emits an error, but why is the error message '.class' expected?
What is Java compiler trying to say?
I suspect the problem is that the only token sequence that can legitimately follow the keyword token of int in this case is . followed by class. The declaration statement you've got at the moment isn't valid because a local variable declaration on its own isn't a Statement as per JLS 14. (It's a BlockStatement.)
Note that in the tutorialspoint environment referenced in the comment, if you use a class instead of int, a different error is produced - potentially because the set of valid tokens is different in that scenario. (String.getClass(); would be valid for example, whereas int.getClass(); wouldn't.)
There is a valid question asked in a comment:
Why this .class thing? If you know any situation in which int followed by .class can compile, then please tell me.
And that's easy - you can call a method on the Class reference returned by int.class:
public class ABC
{
public static void main(String args[])
{
if(true)
int.class.getName();
}
}
That's not useful code, but it is valid code. It compiles for me without warnings or errors.
As mentioned in comments, more recent compiler versions give more useful errors - I would recommend upgrading.
As opposed to what some commenters say, this code can actually produce that error.
int a = 0;
^
According to the Java Language Specification, a variable declaration needs to be in a code block:
Every local variable declaration statement is immediately contained by a block. Local variable declaration statements may be intermixed freely with other kinds of statements in the block.
I assume you already knew that.
But why the .class expected error?
The reason why the exception says .class expected, is compiler specific. Other compilers will emit not a statement or illegal start of expression.
My guess is that it is related to the way the compiler evaluates the code. The only way int can be valid at that location, is when followed by .class. So as soon as the token int is detected, the compiler expects it to be followed by .class.
For example,
if (true)
int.class.getFields();
would be a valid statement.
So the compiler gives an error that is in some way logical, that is, .class expected.
Other compilers probably evaluate the whole statement as a variable declaration, rather than separate tokens like int, a, = and 0.
Specific compiler
I do not know which specific compiler tutorialspoint.com is using, but their javac version (using javac -version) is javac 1.7.0_75 on Fedora release 21 (Twenty One) (using the command cat /etc/issue.net).
PS: I don't know if you have a specific reason for using the compiler of which you posted an image, but I suggest you start using Eclipse or Netbeans.

Mockito: How to verify one method is called on one mock with different parameter in order

I want to test a method of a mock is called in order using different parameters:
I tried to use the following code:
InOrder inOrder = inOrder(myobject);
inOrder.verify(myobject).println(any(String.class));
inOrder.verify(myobject).println(any(String.class));
inOrder.verify(myobject).println("");
inOrder.verify(myobject).println("myfolder");
inOrder.verify(myobject).println("");
inOrder.verify(myobject).println(System.getProperty("user.home"));
However, this does not seem to work as it gave me an error says
inOrder.verify(myobject).println(any(String.class));
has been called for 8 times. This is correct through, but it fails to address the order.
I want to check:
The println method of `myobject` is first called with any string parameter
Then it is called with any string parameter again
Then it is called by an empty string
Then it is called by string "myfolder"
......
How can I achieve this?
EDIT:
Error message is:
org.mockito.exceptions.verification.VerificationInOrderFailure:
Verification in order failure:
printWriter.println(<any>);
Wanted 1 time:
-> at com.mycompany.MyUnitTest.mytest(MyrUnitTest.java:107)
But was 8 times.
Use an argument captor to capture the arguments in all the calls to println, then check each of the captured values that you're interested in.
#Captor ArgumentCaptor<String> stringCaptor;
// ...
#Test public void myTest() {
// ...
verify(myobject, 6).println(stringCaptor.capture());
assertEquals("", stringCaptor.getAllValues()[2]);
assertEquals("myfolder", stringCaptor.getAllValues()[3]);
assertEquals("", stringCaptor.getAllValues()[4]);
assertEquals(System.getProperty("user.home"), stringCaptro.getAllValues()[5]);
David Wallace's solution is the best one I know of that uses Mockito, but remember that mocking isn't always the right tool for the job.
If you can, instead of your mock, pass a PrintWriter(ByteArrayOutputStream) and check that the ByteArrayOutputStream matches the output you expect.
#Test public void yourTest() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintWriter writer = new PrintWriter(baos);
systemUnderTest.doThing(writer);
assertTrue(writer.toString().endsWith(
"\n\nmyfolder\n\n" + System.getProperty(user.home) + "\n"));
}
This is also probably closer to the logic you're actually testing, which is that the output looks the way you expect it, not that the methods were called in exactly the right order. You're then free to refactor any way you'd like, including switching to a MessageFormatter template, or building your newlines into a StringBuilder and calling println once. You're also insulated from anyone who uses any other print or println() call, which would otherwise foul up a Mockito-based test.
You might also use a regex Pattern or Scanner to verify correctness, depending on how specific your needs are. Pattern.quote can help you escape regex substrings if you need to build your expected string programmatically (as you do with user.home here).
Well, this answer is not too general, and is not elegant either.
For me it seems the problem is caused by any(String.class) is greedy, that is, it matches all kind of strings. So, I tried to fabricate a matcher which matches all kind of strings except a few exceptions: "" or "myfolder" or System.getProperty("user.home"). And the code is:
import static org.mockito.AdditionalMatchers.*;
inOrder.verify(myobject, times(2)).println(
and(anyString(), not(
or(eq(""), or(eq("myfolder"), eq(System.getProperty("user.home")))))));
It is a challenge itself to format this to be readable (for some mysterious reason, I can not even extract and(...) to a local variable because it causes a weird runtime exception from mockito that I can not use matcher outside of stubbing or verification).

OO strategy to match a set of tokens to an appropriate method / constructor

This question isn't specifically about performing tokenization with regular expressions, but more so about how an appropriate type of object (or appropriate constructor of an object) can be matched to handle the tokens output from a tokenizer.
To explain a bit more, my objective is to parse a text file containing lines of tokens into appropriate objects that describe the data. My parser is in fact already complete, but at present is a mess of switch...case statements and the focus of my question is how I can refactor this using a nice OO approach.
First, here's an example to illustrate what I'm doing overall. Imagine a text file that contains many entries like the following two:
cat 50 100 "abc"
dog 40 "foo" "bar" 90
When parsing those two particular lines of the file, I need to create instances of classes Cat and Dog respectively. In reality there are quite a large number of different object types being described, and sometimes different variations of numbers of arguments, with defaults often being assumed if the values aren't there to explicity state them (which means it's usually appropriate to use the builder pattern when creating the objects, or some classes have several constructors).
The initial tokenization of each line is being done using a Tokenizer class I created that uses groups of regular expressions that match each type of possible token (integer, string, and a few other special token types relevant to this application) along with Pattern and Matcher. The end result from this tokenizer class is that, for each line it parses, it provides back a list of Token objects, where each Token has a .type property (specifying integer, string, etc.) along with primitive value properties.
For each line parsed, I have to:
switch...case on the object type (first token);
switch on the number of arguments and choose an appropriate constructor
for that number of arguments;
Check that each token type is appropriate for the types of arguments needed to construct the object;
Log an error if the quantity or combination of argument types aren't appropriate for the type of object being called for.
The parser I have at the moment has a lot of switch/case or if/else all over the place to handle this and although it works, with a fairly large number of object types it's getting a bit unwieldy.
Can someone suggest an alternative, cleaner and more 'OO' way of pattern matching a list of tokens to an appropriate method call?
The answer was in the question; you want a Strategy, basically a Map where the key would be, e.g., "cat" and the value an instance of:
final class CatCreator implements Creator {
final Argument<Integer> length = intArgument("length");
final Argument<Integer> width = intArgument("width");
final Argument<String> name = stringArgument("length");
public List<Argument<?>> arguments() {
return asList(length, width, name);
}
public Cat create(Map<Argument<?>, String> arguments) {
return new Cat(length.get(arguments), width.get(arguments), name.get(arguments));
}
}
Supporting code that you would reuse between your various object types:
abstract class Argument<T> {
abstract T get(Map<Argument<?>, String> arguments);
private Argument() {
}
static Argument<Integer> intArgument(String name) {
return new Argument<Integer>() {
Integer get(Map<Argument<?>, String> arguments) {
return Integer.parseInt(arguments.get(this));
}
});
}
static Argument<String> stringArgument(String name) {
return new Argument<String>() {
String get(Map<Argument<?>, String> arguments) {
return arguments.get(this);
}
});
}
}
I'm sure someone will post a version that needs less code but uses reflection. Choose either but do bear in mind the extra possibilities for programming mistakes making it past compilation with reflection.
I have done something similar, where I have decoupled my parser from code emitter, which I consider anything else but the parsing itself. What I did, is introduce an interface which the parser uses to invoke methods on whenever it believes it has found a statement or a similar program element. In your case these may well be individual lines you have shown in the example in your question. So whenever you have a line parsed you invoke a method on the interface, an implementation of which will take care of the rest. That way you isolate the program generation from parsing, and both can do well on their own (well, at least the parser, as the program generation will implement an interface the parser will use). Some code to illustrate my line of thinking:
interface CodeGenerator
{
void onParseCat(int a, int b, String c); ///As per your line starting with "cat..."
void onParseDog(int a, String b, String c, int d); /// In same manner
}
class Parser
{
final CodeGenerator cg;
Parser(CodeGenerator cg)
{
this.cg = cg;
}
void parseCat() /// When you already know that the sequence of tokens matches a "cat" line
{
/// ...
cg.onParseCat(/* variable values you have obtained during parsing/tokenizing */);
}
}
This gives you several advantages, one of which being that you do not need a complicated switch logic as you have determined type of statement/expression/element already and invoke the correct method. You can even use something like onParse in CodeGenerator interface, relying on Java method overriding if you want to always use same method. Remember also that you can query methods at runtime with Java, which can aid you further in removing switch logic.
getClass().getMethod("onParse", Integer.class, Integer.class, String.class).invoke(this, catStmt, a, b, c);
Just make note that the above uses Integer class instead of the primitive type int, and that your methods must override based on parameter type and count - if you have two distinct statements using same parameter sequence, the above may fail because there will be at least two methods with the same signature. This is of course a limitation of method overriding in Java (and many other languages).
In any case, you have several methods to achieve what you want. The key to avoid switch is to implement some form of virtual method call, rely on built-in virtual method call facility, or invoke particular methods for particular program element types using static binding.
Of course, you will need at least one switch statement where you determine which method to actually call based on what string your line starts with. It's either that or introducing a Map<String,Method> which gives you a runtime switch facility, where the map will map a string to a proper method you can call invoke (part of Java) on. I prefer to keep switch where there is not substantial amount of cases, and reserve Java Maps for more complicated run-time scenarios.
But since you talk about "fairly large amount of object types", may I suggest you introduce a runtime map and use the Map class indeed. It depends on how complicated your language is, and whether the string that starts your line is a keyword, or a string in a far larger set.

Java: How to check for null pointers efficiently

There are some patterns for checking whether a parameter to a method has been given a null value.
First, the classic one. It is common in self-made code and obvious to understand.
public void method1(String arg) {
if (arg == null) {
throw new NullPointerException("arg");
}
}
Second, you can use an existing framework. That code looks a little nicer because it only occupies a single line. The downside is that it potentially calls another method, which might make the code run a little slower, depending on the compiler.
public void method2(String arg) {
Assert.notNull(arg, "arg");
}
Third, you can try to call a method without side effects on the object. This may look odd at first, but it has fewer tokens than the above versions.
public void method3(String arg) {
arg.getClass();
}
I haven't seen the third pattern in wide use, and it feels almost as if I had invented it myself. I like it for its shortness, and because the compiler has a good chance of optimizing it away completely or converting it into a single machine instruction. I also compile my code with line number information, so if a NullPointerException is thrown, I can trace it back to the exact variable, since I have only one such check per line.
Which check do you prefer, and why?
Approach #3: arg.getClass(); is clever, but unless this idiom see widespread adoption, I'd prefer the clearer, more verbose methods as opposed to saving a few characters. I'm a "write once, read many" kind of programmer.
The other approaches are self-documenting: there's a log message you can use to clarify what happened - this log message is use when reading the code and also at run-time. arg.getClass(), as it stands, is not self-documenting. You could use a comment at least o clarify to reviewers of the code:
arg.getClass(); // null check
But you still don't get a chance to put a specific message in the runtime like you can with the other methods.
Approach #1 vs #2 (null-check+NPE/IAE vs assert): I try to follow guidelines like this:
http://data.opengeo.org/GEOT-290810-1755-708.pdf
Use assert to check parameters on private methods
assert param > 0;
Use null check + IllegalArgumentException to check parameters on public methods
if (param == null) throw new IllegalArgumentException("param cannot be null");
Use null check + NullPointerException where needed
if (getChild() == null) throw new NullPointerException("node must have children");
HOWEVER, since this is question may be about catching potential null issues most efficiently, then I have to mention my preferred method for dealing with null is using static analysis, e.g. type annotations (e.g. #NonNull) a la JSR-305. My favorite tool for checking them is:
The Checker Framework:
Custom pluggable types for Java
https://checkerframework.org/manual/#checker-guarantees
If its my project (e.g. not a library with a public API) and if I can use the Checker Framework throughout:
I can document my intention more clearly in the API (e.g. this parameter may not be null (the default), but this one may be null (#Nullable; the method may return null; etc). This annotation is right at the declaration, rather than further away in the Javadoc, so is much more likely to be maintained.
static analysis is more efficient than any runtime check
static analysis will flag potential logic flaws in advance (e.g. that I tried to pass a variable that may be null to a method that only accepts a non-null parameter) rather than depending on the issue occurring at runtime.
One other bonus is that the tool lets me put the annotations in a comment (e.g. `/#Nullable/), so my library code can compatible with type-annotated projects and non-type-annotated projects (not that I have any of these).
In case the link goes dead again, here's the section from GeoTools Developer Guide:
http://data.opengeo.org/GEOT-290810-1755-708.pdf
5.1.7 Use of Assertions, IllegalArgumentException and NPE
The Java language has for a couple of years now made an assert keyword available; this keyword can be used to perform debug only checks.
While there are several uses of this facility, a common one is to check method parameters on private (not public) methods. Other uses are
post-conditions and invariants.
Reference: Programming With Assertions
Pre-conditions (like argument checks in private methods) are typically easy targets for assertions. Post-conditions and invariants are sometime
less straighforward but more valuable, since non-trivial conditions have more risks to be broken.
Example 1: After a map projection in the referencing module, an assertion performs the inverse map projection and checks the result
with the original point (post-condition).
Example 2: In DirectPosition.equals(Object) implementations, if the result is true, then the assertion ensures that
hashCode() are identical as required by the Object contract.
Use Assert to check Parameters on Private methods
private double scale( int scaleDenominator ){
assert scaleDenominator > 0;
return 1 / (double) scaleDenominator;
}
You can enable assertions with the following command line parameter:
java -ea MyApp
You can turn only GeoTools assertions with the following command line parameter:
java -ea:org.geotools MyApp
You can disable assertions for a specific package as shown here:
java -ea:org.geotools -da:org.geotools.referencing MyApp
Use IllegalArgumentExceptions to check Parameters on Public Methods
The use of asserts on public methods is strictly discouraged; because the mistake being reported has been made in client code - be honest and
tell them up front with an IllegalArgumentException when they have screwed up.
public double toScale( int scaleDenominator ){
if( scaleDenominator > 0 ){
throw new IllegalArgumentException( "scaleDenominator must be greater than 0");
}
return 1 / (double) scaleDenominator;
}
Use NullPointerException where needed
If possible perform your own null checks; throwing a IllegalArgumentException or NullPointerException with detailed information
about what has gone wrong.
public double toScale( Integer scaleDenominator ){
if( scaleDenominator == null ){
throw new NullPointerException( "scaleDenominator must be provided");
}
if( scaleDenominator > 0 ){
throw new IllegalArgumentException( "scaleDenominator must be greater than 0");
}
return 1 / (double) scaleDenominator;
}
Aren't you optimizing a biiiiiiiiiiiiiiit too prematurely!?
I would just use the first. It's clear and concise.
I rarely work with Java, but I assume there's a way to have Assert only operate on debug builds, so that would be a no-no.
The third gives me the creeps, and I think I would immediately resort to violence if I ever saw it in code. It's completely unclear what it's doing.
You can use the Objects Utility Class.
public void method1(String arg) {
Objects.requireNonNull(arg);
}
see http://docs.oracle.com/javase/7/docs/api/java/util/Objects.html#requireNonNull%28T%29
You should not be throwing NullPointerException. If you want a NullPointerException, just dont check the value and it will be thrown automatically when the parameter is null and you attempt to dereference it.
Check out the apache commons lang Validate and StringUtils classes.
Validate.notNull(variable) it will throw an IllegalArgumentException if "variable" is null.
Validate.notEmpty(variable) will throw an IllegalArgumentException if "variable" is empty (null or zero length".
Perhaps even better:
String trimmedValue = StringUtils.trimToEmpty(variable) will guarantee that "trimmedValue" is never null. If "variable" is null, "trimmedValue" will be the empty string ("").
In my opinion, there are three issues with the third method:
The intent is unclear to the casual reader.
Even though you have line number information, line numbers change. In a real production system, knowing that there was a problem in SomeClass at line 100 doesn't give you all the info you need. You also need to know the revision of the file in question and be able to get to that revision. All in all, a lot of hassle for what appears to be very little benefit.
It is not at all clear why you think the call to arg.getClass can be optimized away. It is a native method. Unless HotSpot is coded to have specific knowledge of the method for this exact eventuality, it'll probably leave the call alone since it can't know about any potential side-effects of the C code that gets called.
My preference is to use #1 whenever I feel there's a need for a null check. Having the variable name in the error message is great for quickly figuring out what exactly has gone wrong.
P.S. I don't think that optimizing the number of tokens in the source file is a very useful criterion.
The first method is my preference because it conveys the most intent. There are often shortcuts that can be taken in programming but my view is that shorter code is not always better code.
x==null is super fast, and it can be a couple of CPU clocks (incl. the branch prediction which is going to succeed). AssertNotNull will be inlined, so no difference there.
x.getClass() should not be faster than x==null even if it uses trap. (reason: the x will be in some register and checking a register vs an immediate value is fast, the branch is going to be predicted properly as well)
Bottom line: unless you do something truly weird, it'd be optimized by the JVM.
The first option is the easiest one and also is the most clear.
It's not common in Java, but in C and C++ where the = operator can be included in a expression in the if statement and therefore lead to errors, it's often recommended to switch places between the variable and the constant like this:
if (NULL == variable) {
...
}
instead of:
if (variable == NULL) {
...
}
preventing errors of the type:
if (variable = NULL) { // Assignment!
...
}
If you make the change, the compiler will find that kind of errors for you.
While I agree with the general consensus of preferring to avoid the getClass() hack, it is worth noting that, as of OpenJDK version 1.8.0_121, javac will use the getClass() hack to insert null checks prior to creating lambda expressions. For example, consider:
public class NullCheck {
public static void main(String[] args) {
Object o = null;
Runnable r = o::hashCode;
}
}
After compiling this with javac, you can use javap to see the bytecode by running javap -c NullCheck. The output is (in part):
Compiled from "NullCheck.java"
public class NullCheck {
public NullCheck();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: aconst_null
1: astore_1
2: aload_1
3: dup
4: invokevirtual #2 // Method java/lang/Object.getClass:()Ljava/lang/Class;
7: pop
8: invokedynamic #3, 0 // InvokeDynamic #0:run:(Ljava/lang/Object;)Ljava/lang/Runnable;
13: astore_2
14: return
}
The instruction set at "lines" 3, 4 and 7 are basically invoking o.getClass(), and discarding the result. If you run NullCheck, you'll get a NullPointerException thrown from line 4.
Whether this is something that the Java folks concluded was a necessary optimization, or it is just a cheap hack, I don't know. However, based on John Rose's comment at https://bugs.openjdk.java.net/browse/JDK-8042127?focusedCommentId=13612451&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-13612451, I suspect that it may indeed be the case that the getClass() hack, which produces an implicit null check, may be ever so slightly more performant than its explicit counterpart. That said, I would avoid using it unless careful benchmarking showed that it made any appreciable difference.
(Interestingly, the Eclipse Compiler For Java (ECJ) does not include this null check, and running NullCheck as compiled by ECJ will not throw a n NPE.)
I'd use the built-in Java assert mechanism.
assert arg != null;
The advantage of this over all the other methods is that it can be switched off.
I prefer method 4, 5 or 6, with #4 being applied to public API methods and 5 / 6 for internal methods, although #6 would be more frequently applied to public methods.
/**
* Method 4.
* #param arg A String that should have some method called upon it. Will be ignored if
* null, empty or whitespace only.
*/
public void method4(String arg) {
// commons stringutils
if (StringUtils.isNotBlank(arg) {
arg.trim();
}
}
/**
* Method 5.
* #param arg A String that should have some method called upon it. Shouldn't be null.
*/
public void method5(String arg) {
// Let NPE sort 'em out.
arg.trim();
}
/**
* Method 6.
* #param arg A String that should have some method called upon it. Shouldn't be null.
*/
public void method5(String arg) {
// use asserts, expect asserts to be enabled during dev-time, so that developers
// that refuse to read the documentations get slapped on the wrist for still passing
// null. Assert is a no-op if the -ae param is not passed to the jvm, so 0 overhead.
assert arg != null : "Arg cannot be null"; // insert insult here.
arg.trim();
}
The best solution to handle nulls is to not use nulls. Wrap third-party or library methods that may return nulls with null guards, replacing the value with something that makes sense (such as an empty string) but does nothing when used. Throw NPE's if a null really shouldn't be passed, especially in setter methods where the passed object doesn't get called right away.
There is no vote for this one, but I use a slight variation of #2, like
erStr += nullCheck (varName, String errMsg); // returns formatted error message
Rationale: (1) I can loop over a bunch of arguments, (2) The nullCheck method is tucked away in a superclass and (3) at the end of the loop,
if (erStr.length() > 0)
// Send out complete error message to client
else
// do stuff with variables
In the superclass method, your #3 looks nice, but I wouldn't throw an exception (what is the point, somebody has to handle it, and as a servlet container, tomcat will ignore it, so it might as well be this())
Regards, - M.S.
First method. I would never do the second or the third method, not unless they are implemented efficiently by the underlying JVM. Otherwise, those two are just prime examples of premature optimization (with the third having a possible performance penalty - you don't want to be dealing and accessing class meta-data in general access points.)
The problem with NPEs is that they are things that cross-cut many aspects of programming (and my aspects, I mean something deeper and more profound that AOP). It is a language design problem (not saying that the language is bad, but that it is one fundamental short-coming... of any language that allows null pointers or references.)
As such, it is best to simply deal with it explicitly as in the first method. All other methods are (failed) attempts to simplify a model of operations, an unavoidable complexity that exists on the underlying programming model.
It is a bullet that we cannot avoid to bite. Deal with it explicitly as it is - in the general case that is - the less painful down the road.
I believe that the fourth and the most useful pattern is to do nothing. Your code will throw NullPointerException or other exception a couple of lines later (if null is illegal value) and will work fine if null is OK in this context.
I believe that you should perform null check only if you have something to do with it. Checking to throw exception is irrelevant in most cases.
Just do not forget to mention in javadoc whether the parameter can be null.

Categories

Resources