Bummer! This is just a preview. You need to be signed in with a Basic account to view the entire video.
Start a free Basic trial
to watch this video
During this final video of the course, we'll use what we learned about reflection to examine the MathUtils
class, checking to see if proper @Doc
annotations have been applied.
Popular Libraries Leveraging Annotations
Java libraries that make heavy use of annotations are seemingly endless. Here are just a few of the most popular ones:
- Spring - writing standard web applications, creating a RESTful API, running batch processes, and more!
- JUnit - create small, repeatable tests that ensure the functionality of your application's individual components
- Hibernate - wire Java objects to databases
- Butter Knife - wire GUI elements from Android views to the code that controls them
-
0:00
If you didn't take the time earlier to scan the logic of this class, go ahead and
-
0:03
pause the video now and take a peek.
-
0:05
When you get the gist of it, un-pause and we'll continue.
-
0:08
Everything that needs to be done is documented with a to do comment, so
-
0:11
let's jump right in.
-
0:13
To check if an annotation is present on a class or
-
0:15
a method, the code is quite simple and intuitive.
-
0:18
We'll use the class objects, isAnnotationPresent() method.
-
0:23
So in place of true, I will type clazz.
-
0:27
I'm gonna call this variable clazz, so
-
0:30
it's not confused with class, isAnnotationPresent().
-
0:35
And I'll press Doc.class.
-
0:36
So, I tell the class object exactly what annotation I'm looking for.
-
0:42
Next up is looping over the declared methods of the class object.
-
0:45
We did this while practicing.
-
0:46
So here, instead of looping over an empty array, which I have right here, we'll use
-
0:52
the getDeclaredMethods method to return an array of the classesDeclared methods.
-
0:58
clazz.getDeclaredMethods().
-
1:04
Now, let's get the modifiers the current method.
-
1:07
This is accomplished with the get modifiers method.
-
1:09
Remember, this comes back as an int.
-
1:11
We'll be making more meaningful use of this int in just a moment.
-
1:14
So in place of this string approach that we took in practicing reflection,
-
1:19
we're gonna store this as an int.
-
1:21
int, and I'll call it modifierInt
-
1:27
= method.getModifiers.
-
1:31
Getting the method name was also simple and straightforward.
-
1:34
We use the getName() method.
-
1:36
So in place of null, method.getName().
-
1:41
Now back to those modifiers.
-
1:43
We need to use what's store in modifierInts to check whether or
-
1:46
not the private modifier is present.
-
1:48
We could use the approach we did earlier.
-
1:50
Convert the int to a modifier string and
-
1:52
then check to see if that string contains the word private.
-
1:55
But, there's another method in the Modifier class
-
1:58
that will get us there one step sooner.
-
2:01
It's the isPrivate() method, and it's a static method.
-
2:04
So in place of true I will check to see if the modifier is private and
-
2:10
I'll pass it the modifierInt that I got back from calling getModifiers() up above.
-
2:18
Now of course, I want to check to see if the method is non-private, so I'm going to
-
2:22
negate this boolean value that comes back with the exclamation point.
-
2:26
I also realized that I'd introduced the Modifier class for
-
2:29
the first time in this file.
-
2:31
So let's go to the top and import the modifier class.
-
2:35
Import jaba.lang.reflect.Modifier.
-
2:40
Brilliant, scrolling back down,
-
2:43
next we'll need to check and see if the annotation appears on the method.
-
2:48
Right here, in place of this true,
-
2:50
will also call the isAnnotationPresent() on the method.
-
2:53
So, I'll call method.isAnnotationPresent().
-
2:59
Again, past the .class, so it knows which annotation we're actually looking for.
-
3:05
The next to do is a critical one, and one we haven't practiced yet, but
-
3:08
it's also really easy.
-
3:10
This will be the piece of code that gives us access to the actual element values
-
3:14
on the individually placed annotations.
-
3:16
That is, we'll be able to read the details of a specific annotation.
-
3:20
For example, what description was indeed provided?
-
3:24
Or, how many parameters were actually documented?
-
3:28
What we need to do is fetch the annotation itself as a doc object, so that we can
-
3:32
call the interface methods, or elements, that we defined in the annotation.
-
3:37
To do this, we'll call the methods getAnnotation() method.
-
3:41
method.getAnnotation(), again specifying which
-
3:46
annotation it is that we'd like to get.
-
3:50
The rest of our coding falls into the two methods at the bottom of the class.
-
3:53
getNumMissingParams(), right here, as well as hasReturnDescription(),
-
3:58
the last method at the bottom here.
-
4:00
Let's start with getNumMissingParams().
-
4:04
Our first order of business is comparing the number of parameters to
-
4:07
the number of parameters document.
-
4:09
We'll first put each piece of information into a variable and
-
4:12
then use those values in simple comparison.
-
4:14
So, after these to do comments, I'll create a couple of variables.
-
4:17
The first one I'm gonna call annotedParamCount.
-
4:21
This will be the number of parameters that were documented in the annotation itself.
-
4:26
So, to find that I will say doc.paramas().length.
-
4:32
Remember, the params element that we declared in the annotation is
-
4:36
a string array.
-
4:38
Since it's a string array, we have access to the length property.
-
4:42
Okay, my next variable I'm going to call actualParamCount.
-
4:47
This variable will store the actual number of parameters on the method object.
-
4:52
method.GetParameterCount().
-
4:57
Finally, to compare the two values in place of true,
-
5:00
we'll use those two variable names that we just declared and stored values into.
-
5:05
So if the annotatedParamCount < actualParamCount
-
5:14
Then we must have some missing parameters.
-
5:16
So, how do we calculate that?
-
5:17
Well, that is simply a subtraction problem between those two values.
-
5:21
So, numMissing = actualParamCount- annotatedParamCount.
-
5:31
On to our last method, hasReturnDescription().
-
5:35
For this method, we want to return true in two scenarios.
-
5:39
Either a, the method is a void method, or
-
5:41
b, the method's annotation has a non-empty return val element.
-
5:46
Let's write a boolean expression for just that.
-
5:49
To return true in the first scenario,
-
5:51
I'll check to see if the method's return type is Void.
-
5:53
To do this, I'll call the getReturnType() method on the method object,
-
5:58
getReturnType(), and we'll see if its value equals Void.TYPE.
-
6:06
In the second scenario,
-
6:07
we wanna return true when the annotations returnVal element is empty.
-
6:13
So to check that, we'll say doc.returnVal.isEmpty.
-
6:19
We wanna check for nonempty returnVals, so
-
6:22
again, I'll negate that boolean value with the exclamation point.
-
6:29
At this point we've finished coding the analysis of our annotation.
-
6:32
One of the cool things here, is that there's nothing that we wrote that is
-
6:35
specific to the MathUtils class, which means that we can
-
6:39
use this DocProcessor class to analyze the doc annotation of any class we like.
-
6:44
Let's test all this code by hopping over to the Main class and
-
6:47
calling the DocProcessor's, processor method.
-
6:50
I'll first remove all of our test code that we wrote while we were practicing
-
6:53
reflection.
-
6:56
So I'll call DocProcessor.process and pass it MathUtils.
-
7:05
And we're ready to compile and run.
-
7:08
So back in our console, I'll compile with javac.
-
7:12
Specify the out directory as a placement for our class files, set the class
-
7:17
path as the src directory, and we'll type the file that we wanna compile.
-
7:30
It looks like we have an error here.
-
7:31
Let's check it out and see if we can troubleshoot this.
-
7:35
Looks like I mistyped a variable name in DocProcessor.java on line 109.
-
7:40
Let's hop over there and correct that error and recompile.
-
7:44
Line 109 is right here.
-
7:49
Looks like that should be annotatedParamCount.
-
7:52
I'll correct that, and let's see if that was our only error.
-
7:55
It's saying one error in our compiler results.
-
7:57
So, I'm pretty confident here.
-
8:00
Recompile.
-
8:04
Great, I'm gonna clear.
-
8:06
Give myself a little more room for output.
-
8:09
And let's run this program.
-
8:11
I'll set the class path as the out directory and
-
8:16
let's run com.teamtreehouse.docgen.Main.
-
8:23
Great, it finds both our sufficient and
-
8:25
insufficient documentation on the MathUtils class.
-
8:29
I'll leave fixing the insufficient documentation as an exercise for
-
8:32
you after this video.
-
8:35
Now that we've looked at the basics of annotations,
-
8:37
experimented with the built-in annotations and
-
8:40
even built one of our own, you're ready to encounter them in the wild.
-
8:44
I've linked to some resources in the teacher's notes for
-
8:46
further research, including a few popular libraries that utilize annotations.
-
8:52
Having trouble with a specific library?
-
8:54
Be sure to hit up the forums of those libraries, or
-
8:57
even broader coding forums like StackOverflow.
-
9:00
Chances are,
-
9:01
the answer you're looking for is sitting out there waiting for your visit.
-
9:05
Happy annotating!
You need to sign up for Treehouse in order to download course files.
Sign up