Annotations have been around since Java 1.6 and use a special “@interface” declaration, which, in itself, uses an annotation to define what sort of annotation is being created.
There are many different uses for annotations, from purely use for documentation, to enforcing client-side (IDE) validation, to boilerplate abstraction.
Here are a few annotations that we use internally at 3SC.
Google support annotations:
These annotations are incredibly useful because they use the power of lint to warn you if you try to pass something to an annotated method that could potentially throw an error. For example, the @NonNull method enforces that the object can not be null when passed to it.
public void test(@NonNull String var)
test(null); // lint error will trigger here
In the above example, a lint error will be triggered in Android Studio to tell us that we’re passing a potentially (in this case, definitely) null object.
Another good annotation is the @Nullable. Unlike @NonNull, it won’t trigger a lint error, but is more of a developer annotation that allows the developer to know that it is safe to pass null to an annotated parameter.
Lombok is probably my absolute favourite annotation library ever. I started using it back in 2012, back in the days of using Eclipse, and it has made my life much easier and has saved so much time in writing convenience methods. The main use of this annotation lib is the @Getter and @Setter annotations which, when annotated on a field (or class), generate getters/setter methods for that annotated member. Note that this isn’t a library that creates runtime code using reflection, but instead actually generates code at compile time. This makes it incredibly efficient as reflection can be slow.
There are a bunch of other useful annotations in Lombok which i’ve recently discovered, such as @Getter(lazy = true), @Data, @Builder.
@Getter(lazy = true) works exactly like the normal @Getter annotation, but creates a lazy initiator which is useful for singletons.
@Data is used on a class level and generates toString() and equals() methods that use all the members in the containing class
@Builder is used for creating a convenient builder class in the same style as AlertDialog.Builder
Now this annotation library is my own personal one I wrote a few years back which is heavily based off Jake Wharton’s Butter Knife library (I’d personally recommend using his rather than mine). This library (or just single file) is a convenience class that allows for view injecting into variables using either its perma ID reference, or the variable name.
The reason I wrote my own library was because at the time (of Eclipse) I couldn’t get Butter Knife working nicely, so I wrote my own version that used reflection instead of compile time generation (which is what Butter Knife does). Although reflection is bad and slow, it’s quite negligible so long as you don’t have thousands of views being injected.
There are some nice additions that I added that are not available in Butter Knife (as far as I’m aware) such as generated onClick handling, multiple view injection into arraylist, injecting fragments, etc. The main reason why we still use this library is for legacy reasons, and because I like using things that I wrote ☺
In conclusion, annotations are great. They save time, remove boilerplate and are generally just nice to use. There’s absolutely no reason you can’t use annotations for things like documentation or enforcement for certain parameters (such as the helpful Android annotation ref tool).
You can read more about annotations here or even learn how to create one here.