In my program there is the following piece of code where I must delete a ' '
from the second to last index in a StringBuilder
:
builder.deleteCharAt(builder.length() - 2);
I do not surround it with checks to either condition builder.length() >= 2
or builder.charAt(builder.length() - 2) == ' ')
, because I am 100% sure that both these conditions will always be true, even though at first glance, it is not so obvious.
I'm torn between feeling that just because I have a higher understanding of the code, doesn't mean I should neglect the conditions for the sake of others in the team. But at the same time, if I do check for these conditions, it would be absolutely unnecessary.
My solution is to simply add a comment, but I was wondering if is this considered to be good practice?
builder.deleteCharAt(builder.length() - 2); // should always be ' '
2 Answers 2
Don't use a comment. Use code. Specifically, assert builder.length() >= 2
and assert builder.charAt(builder.length() -2) == ' '
. Assertions will clearly indicate the preconditions, and they can be excluded by the compiler or jvm so they don't impact the deployed code.
I'm torn between feeling that just because I have a higher understanding of the code, doesn't mean I should neglect the conditions for the sake of others in the team.
That feeling you have is "encapsulation" or the principle of least information, or whatever kids call it these days.
If this problem is occurring across files, modules, classes, functions, or some other boundary you feel establishes a "library/client" relationship, then the StringBuilder
-manipulating code should not assume your precondition, and you definitely should not assume clients of your code are going to open up your implementation and read your comment to learn what they can't do.
Better options include:
- document the precondition in the function's documentation.
- use an assert.
- throw an error (in Java this would mean don't do any check).
If the problem is occurring within one function or file, then either way is fine. For instance in this block:
if(!myString.isEmpty()) {
// do something else...
System.out.println(myString[0]);
}
You will notice that the reader may very well have forgotten about the "if"-check. That's okay. There's a line somewhere where the reader needs to have some knowledge of the code. That being said:
- your "should always be " "" comment is not very good. It doesn't tell me why, and of course comments do not run so I do not even know if I trust it.
- Code is better than comments. I think an assert is just as bad because it leaves me with the question "why won't this assert fire?" which is the same question I had when read your code anyway.
assert
is a great way to handle this problem as stated below. \$\endgroup\$String
"A.M."
becomes["A", ".", "M", "."]
. After processing the first three tokens, theStringBuilder
holds the stringA . M
and the current token is"."
. Based on certain flags I've set, I determine I've come across an acronym. So here is where I callbuilder.deleteCharAt(builder.length() - 2);
to delete the second to last character in theStringBuilder
. \$\endgroup\$