Skip to content
This repository has been archived by the owner on May 28, 2022. It is now read-only.

Java: add guidelines for using assertions #37 #38

Merged
merged 1 commit into from
Mar 18, 2017

Conversation

damithc
Copy link
Contributor

@damithc damithc commented Jan 27, 2017

Fixes #37
Fixes #19

Let's specify guidelines for using Java assertions in a new document
that will accumulate more such higher-level Java guidelines in future.

@damithc damithc force-pushed the 37-additional-java-guidelines branch 2 times, most recently from 86176ba to e14f5b1 Compare January 27, 2017 09:52
@CanIHasReview-bot
Copy link

v1

@damithc submitted v1 for review.

(📚 Archive)

Checkout this PR version locally
git fetch https://github.com/oss-generic/process.git refs/pr/38/1/head:BRANCHNAME

where BRANCHNAME is the name of the local branch you want to fetch this PR to.

@@ -0,0 +1,98 @@
# Additional Guidelines - Java

## Argument validation
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't find a good reference for this section, so had to cook up my own guidelines. Do review with a very critical mind.

```

Furthermore, place the argument validation code immediately above the first line of code it tries to defend, so that
the reader can easily deduce the reason for argument validation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I always thought to validate early, if at all, to avoid unnecessary processing if it's gonna fail anyway.
Surprisingly, despite searching for the past half hour or so, I couldn't find an authoritative guide.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed @acjh , validating arguments upfront seems like the natural thing to do and I used to do it that way too. However, now that the decision to validate depends on a specific circumstances in the code, it seems safer to put the validation near the 'reason for validation' so that if the 'reason for validation' changes, the validation code too can be changed accordingly. For example, if the 'reason for validation' code is extracted to another method, the validation code can go with it. But I don't feel strongly about it; it's just something I cooked up (and yes, I too could not find a good reference to derive from).

@wkurniawan07
Copy link

Sorry for the delay. I'll give a review by tomorrow.

Copy link

@wkurniawan07 wkurniawan07 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just two minor items.

There are a handful of coding style violations though, all revolving missing whitespace:

  • Between ) and {
  • Between if and (

```

In the example below, `key` need not be validated against `null` because a `null` value is going to create a
detectable failure (i.e. a `NullPointerException`) anyway.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this may be accurate,

  • NullPointerException is a special case; most developers would try their best to avoid this at all costs rather than "letting it happen and catching it somewhere".
  • It also depends on the method signature; if the method is designed to "return null/false if the argument is null", then this explanation will not apply anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NullPointerException is a special case; most developers would try their best to avoid this at all costs rather than "letting it happen and catching it somewhere".

That's true. I think 'avoid the NPE at all costs' aspect is addressed by the new Optional feature to some extent. Assuming asserts are being used to identify programmer errors while testing (i.e. they are not enabled in production -- java doesn't have a way to enable asserts when run from an executable jar file), our objective is to identify programmer errors and the choice in this example is between an assertion failure and an NPE. Assertion failure cost us an extra line of code and (i.e. assert key != null) and tells us precisely what parameter is null. NPE happens in the same method, but slightly harder to trace back to the offending parameter.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@damithc

our objective is to identify programmer errors and the choice in this example is between an assertion failure and an NPE. Assertion failure cost us an extra line of code and (i.e. assert key != null) and tells us precisely what parameter is null. NPE happens in the same method, but slightly harder to trace back to the offending parameter.

Java 7 and above actually has an Objects::requireNonNull() method which might be useful in this regard.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Java 7 and above actually has an Objects::requireNonNull() method which might be useful in this regard.

Didn't know such a thing existed :-p But it's not a replacement for assert? Probably it's more useful when we want to have argument checking in public APIs where asserts are not recommended.

Another related feature that might be relevant is annotations https://blogs.oracle.com/java-platform-group/entry/java_8_s_new_type Unfortunately, it's not supported in the standard jdk though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just realized my comments above are not correct. I mixed up assertions (covered in a different guideline) with argument validation covered in this section.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@damithc what is the standard for this case if I want to throw a NullPointerException with a custom error message (to help debugging)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@damithc what is the standard for this case if I want to throw a NullPointerException with a custom error message (to help debugging)?

In that case we can use something like Objects#requireNonNull(Object o, String message) ?


```java
void setName(String name){
this.saveName(name);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not directly related to the guideline, but do we have an agreement on usage of this? I always thought that unless absolutely necessary (like this.name = name;), this should always be dropped.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll create a separate issue for it. Will remove this. from here.

@damithc damithc force-pushed the 37-additional-java-guidelines branch from e14f5b1 to 8f78d58 Compare February 19, 2017 03:29
@CanIHasReview-bot
Copy link

v2

@damithc submitted v2 for review.

(📚 Archive) (📈 Interdiff between v1 and v2)

Checkout this PR version locally
git fetch https://github.com/oss-generic/process.git refs/pr/38/2/head:BRANCHNAME

where BRANCHNAME is the name of the local branch you want to fetch this PR to.

@damithc
Copy link
Contributor Author

damithc commented Feb 19, 2017

Please ignore v2. I missed some review comments.

@damithc damithc force-pushed the 37-additional-java-guidelines branch from 8f78d58 to 0d0a027 Compare February 19, 2017 03:34
@CanIHasReview-bot
Copy link

v3

@damithc submitted v3 for review.

(📚 Archive) (📈 Interdiff between v2 and v3)

Checkout this PR version locally
git fetch https://github.com/oss-generic/process.git refs/pr/38/3/head:BRANCHNAME

where BRANCHNAME is the name of the local branch you want to fetch this PR to.

@damithc
Copy link
Contributor Author

damithc commented Feb 19, 2017

V2+V3:

  • Fixed problems mentioned by reviews
  • Mentioned Objects#requireNonNull()

MightyCupcakes added a commit to MightyCupcakes/addressbook-level4 that referenced this pull request Feb 21, 2017
The use of asserts in the validation of parameters will result in
a generic AssertionError whenever an invalid parameter is passed
in.

This is not desirable as assertions should not be used for parameter
validation. It should be enforced by explict checks that throw
specific exceptions.

Let's modify all methods in the Commons package that uses
exception to follow this new rule

See: oss-generic/process#38
MightyCupcakes added a commit to MightyCupcakes/addressbook-level4 that referenced this pull request Feb 21, 2017
The use of asserts in the validation of parameters will result in
a generic AssertionError whenever an invalid parameter is passed
in.

This is not desirable as assertions should not be used for parameter
validation. It should be enforced by explict checks that throw
specific exceptions.

Let's modify all methods in the Commons package that uses
exception to follow this new rule

See: oss-generic/process#38
MightyCupcakes added a commit to MightyCupcakes/addressbook-level4 that referenced this pull request Feb 21, 2017
The use of asserts in the validation of parameters will result in
a generic AssertionError whenever an invalid parameter is passed
in.

This is not desirable as assertions should not be used for parameter
validation. It should be enforced by explict checks that throw
specific exceptions.

Let's modify all methods in the Commons package that uses
exception to follow this new rule

See: oss-generic/process#38
@damithc damithc force-pushed the 37-additional-java-guidelines branch from 0d0a027 to 91d71d9 Compare February 27, 2017 14:54
@damithc damithc changed the title Document additional Java coding guidelines #37 Java: add guidelines for using assertions #37 Feb 27, 2017
@CanIHasReview-bot
Copy link

v4

@damithc submitted v4 for review.

(📚 Archive) (📈 Interdiff between v3 and v4)

Checkout this PR version locally
git fetch https://github.com/oss-generic/process.git refs/pr/38/4/head:BRANCHNAME

where BRANCHNAME is the name of the local branch you want to fetch this PR to.

@damithc
Copy link
Contributor Author

damithc commented Feb 27, 2017

v4:

Removed guidelines on argument validation as they are not stable yet. Assertion guidelines are more stable and can be merged sooner.

Argument validation is to be discussed in #71

@damithc
Copy link
Contributor Author

damithc commented Mar 4, 2017

Any more comments about this? If not, i'll be merging soon.


Refer the article
_[Programming With Assertions](http://docs.oracle.com/javase/7/docs/technotes/guides/language/assert.html)_
(from Oracle) for more details on the three general guidelines below.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will update as suggested.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@damithc The first point not corrected in v5?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, missed that. Will correct in next iteration.

@@ -0,0 +1,44 @@
# Additional Guidelines - Java

## Using assertions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Section headings should use Title Case like in the other coding standards (linked here for convenience):

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on this which we are going to adopt soon, headings should be sentence case. Keep this in sentence case and revise coding standards docs later to match the guideline?

Copy link

@wkurniawan07 wkurniawan07 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@damithc damithc force-pushed the 37-additional-java-guidelines branch from 91d71d9 to b6fdb40 Compare March 12, 2017 03:04
@CanIHasReview-bot
Copy link

v5

@damithc submitted v5 for review.

(📚 Archive) (📈 Interdiff between v4 and v5)

Checkout this PR version locally
git fetch https://github.com/oss-generic/process.git refs/pr/38/5/head:BRANCHNAME

where BRANCHNAME is the name of the local branch you want to fetch this PR to.

@damithc
Copy link
Contributor Author

damithc commented Mar 12, 2017

v5: changed link from java 7 documentation to java 8 documentation

We have a Java coding standard to specify syntax level guidelines.
Higher level guidelines such as when to use assertions are not documented.

Let's add a document to specify those additional guidelines for Java.
Include in that document guidelines for using assertions.
@damithc damithc force-pushed the 37-additional-java-guidelines branch from b6fdb40 to 2eff23e Compare March 13, 2017 14:20
@CanIHasReview-bot
Copy link

v6

@damithc submitted v6 for review.

(📚 Archive) (📈 Interdiff between v5 and v6)

Checkout this PR version locally
git fetch https://github.com/oss-generic/process.git refs/pr/38/6/head:BRANCHNAME

where BRANCHNAME is the name of the local branch you want to fetch this PR to.

@damithc
Copy link
Contributor Author

damithc commented Mar 14, 2017

Going to merge soon. cc: @pyokagan

@damithc damithc merged commit 2b68af8 into master Mar 18, 2017
@damithc damithc deleted the 37-additional-java-guidelines branch March 18, 2017 03:05
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants