views:

95

answers:

4

What's the best practise when adapting C-style functions which return a true/false to Java?

Here's a simple method to illustrate where the problem lies.

public static boolean fileNameEndsWithExtension( String filename, String fileExtension)  { 
    return filename.endsWith( fileExtension );
}

Note that there's probably a more elegant way of filtering files (feel free to comment on this). Anyway, if filename is a null value, does one:

  1. Return a false if filename is null? If so, how does one go about distinguishing between the case where filename is null and the case where the String or file name doesn't end with a given file extension?
  2. Change the return type to the wrapper class Boolean which allows a null value.
  3. Throw an Exception and force the programmer to make sure that a null value is never passed to the method?
  4. Use another solution?
+3  A: 

You do what makes sense in the problem domain of your particular application:

  1. If it makes sense to say that the empty set of filenames ends with any extension, return true.
  2. If it makes sense to say that the empty set of filenames ends with no extension, return false.
  3. If it makes sense to say that no one should ever ask this question, let the code throw.
  4. If it makes sense to have a three-values result, sure, use Boolean.
  5. Or make a three-valued enum and return from THAT.

Most of the time, option 3 is going to be sensible, but no one here can rule out the applicability of the others to your application. If you pass a lot of meaningful null filenames around for a good reason, it might make sense to choose one of the others.

bmargulies
+7  A: 

You should throw a NullPointerException or an IllegalArgumentException if filename is null. I'll let you decide which is best. There's a good debate on which to use in the question: IllegalArgumentException or NullPointerException for a null parameter?

GaryF
+1 of course if you just leave it as it is you will already get an appropriate `NullPointerException`; I probably wouldn't bother do any more. Options 1 and 2 are horrible, as they'll postpone the error until a later point where it may be harder to debug.
bobince
On NPE vs IAE: I would recommend NPE as it's widely used through the standard library to signal that an argument was illegally `null`. Java 7 will even introduce `java.util.Objects` which will have a utility method for one-line anti-null checking and assignment (giving an NPE if the argument is null). NPEs have simply become the way to do it. Related RFE: http://bugs.sun.com/view_bug.do?bug_id=6889858
gustafc
That's nice to hear. It would save having a utility method to check for null values.
James P.
+2  A: 

I would use either 1 or 3. Preferably I would throw NullPointerExceptions or atleast use an assert.

Returning nullable Booleans usually causes more trouble than they are worth, you have check for nulls etc. Besides fileNameEndsWithExtension() looks like a function that you'll be using only when you know that you have a valid filename.

Also do not forget that fileExtension might also be a null.

Juha Syrjälä
+1  A: 
  1. return true IFF filename.endsWith( fileExtension )

I would return false if filename is null, and not bother with the distinction between null and any other non-matching values.

If null filename is a distinct state that needs to be verified and handled specifically, then this should be validated separately, preferably before checking endsWith(), but still retain the null check in endsWith() to prevent unnecessary runtime exceptions.

The reason that I would choose the behaviour of null = false, is probably due to influence from relational databases. The following query would only return rows which match the condition, everything else (nulls and mismatches) would be ignored.

select * from filenames
 where filename like '&fileExtension';
crowne
I understand the reasoning as it's what I was used to before. Incidentally, a getResult() with JQL/JPA/Hibernate would also return a null value (usually allocated to a List).
James P.