Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Tim Cooke
  • Jeanne Boyarsky
  • Liutauras Vilda
Sheriffs:
  • Frank Carver
  • Henry Wong
  • Ron McLeod
Saloon Keepers:
  • Tim Moores
  • Frits Walraven
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
Bartenders:
  • Al Hobbs
  • Piet Souris
  • Himai Minh

Assert Public Method Arguments

 
Ranch Hand
Posts: 531
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Asserts provide method contract enforcement above and beyond simple type checking. Assertions must be distinguished from exceptions in that they aren't supposed fail in released code. In fact you should ensure that if you have an assertion you have a unit test that covers it. The assertions become extensions of the syntax and type checking offered by the compiler.

Sun recommends that you DO NOT assert public method arguments and I find that suggestion misguided. I would assert on public method argument unless you are publishing an API for general consumption. In that case you should throw IllegalArgumentException and that should be tested also.

Consider this: if your public methods have more to do with accessibility from your other internal packages, then you can benefit emmensely from assertions, just as you do in your protected and private methods. Most of the time you control the whole code base for an application or utility and you're not publishing an API.

Consider a set of method calls that are private, package or protected. You have assertions in those methods and the result is very robust. You cannot refactor those to be public later on withou removing the asserts and throwing an exception according to Sun. That's nonsense. All you did was expose the method to some other internal package. If you offered it as a general purpose API that was not specific to your project, then fine, by all means change the asserts to IllegalArgumentExceptions.

I believe this "do not assert public method arguments" is misguided dogma that twists "public" to mean something that was never intended. The use of assert should be guided by the use of that method; not whether it's public.
 
Ranch Hand
Posts: 781
Netbeans IDE Ubuntu Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm with you on this.

Before 'assert' was introduced, to implement 'design by contract' I had a load of 'if' statements at the start of each published method. Each 'if' statement would result in an IllegalArgumentException if true. This worked reasonably well but there was no (simple) way to turn off these checks in a production environment.

'assert' changed all of that. Now my code is more compact, reads better and I can very simply turn off the checks in production.

'assert' is far from perfect for use in 'design by contract' but it is better than just throwing IllegalArgumentException.
 
Rick O'Shay
Ranch Hand
Posts: 531
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, but, the IllegalArgumentException is still required in public methods in those rare instances that Sun incorrectly assumes is the norm: publishing an API for the world at large.

Despite protests from his fellow cube rats, Sloppy Sam thinks unit testing is for girls (he's also a gender bigot) and he thinks assertis a breath mint. His team puts out quality code because QA just keeps kicking it back until it's right.

If you quietly continue with a bad argument you could introduce a bug in Sam's code that neither he nor his cube rat crew are capable of finding. If you throw an IllegalArgumentException, that'll get his attention and won't be masked at runtime.
 
James Sabre
Ranch Hand
Posts: 781
Netbeans IDE Ubuntu Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Rick O'Shay:
Yes, but, the IllegalArgumentException is still required in public methods in those rare instances that Sun incorrectly assumes is the norm: publishing an API for the world at large.



I don't see this! I use assert when "publishing an API for the world at large". What would be the advantage of using IllegalArgumentException?
 
Ranch Hand
Posts: 323
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
when other code uses your code incorrectly, and your code does whatever it does to indicate it's been abused by bad input, it's much easier and more intuitive for the other code to try and catch an IllegalArgumentException than it is to understand why your code suddenly caused an AssertionError.

after all, how often have you written "catch (AssertionError e)" on somebody else's code, as opposed to "catch (IllegalArgumentException e)"? don't you think the latter is far more descriptive of what actually happened?
 
author and iconoclast
Posts: 24204
44
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by M Beck:

after all, how often have you written "catch (AssertionError e)" on somebody else's code, as opposed to "catch (IllegalArgumentException e)"? don't you think the latter is far more descriptive of what actually happened?



You should not write either; it's like catching NullPointerException. All of these are represent programming errors. They're supposed to happen during testing, so you can fix them.
 
Rick O'Shay
Ranch Hand
Posts: 531
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Ernest Friedman-Hill:


You should not write either; it's like catching NullPointerException. All of these are represent programming errors. They're supposed to happen during testing, so you can fix them.



Absolutely, and perhaps that sheds some light on Sun's assertion (no pun intended) that you should not assert on public method arguments: you want a runtime exception that cannot be disabled.

I, of course, maintain that asserts can be used regardless of the access attribute to gain the benefits and simplify refactors and maintenance. The exception is publishing classes for the world at large where you have zero control over how it's tested and used.
 
We can fix it! We just need some baling wire, some WD-40, a bit of duct tape and this tiny ad:
the value of filler advertising in 2021
https://coderanch.com/t/730886/filler-advertising
reply
    Bookmark Topic Watch Topic
  • New Topic