Fundamentals 8 min read

Understanding Java Annotations with Practical Examples and a Simple ButterKnife Implementation

This article introduces Java annotations, explains their three main purposes—documentation, compile‑time checks, and runtime code analysis—demonstrates how to define and use custom annotations, and walks through a handcrafted ButterKnife‑like example that binds UI elements via reflection.

Java Captain
Java Captain
Java Captain
Understanding Java Annotations with Practical Examples and a Simple ButterKnife Implementation

Java annotations, introduced in JDK 1.5, are metadata that can be used for documentation generation, compile‑time validation, and runtime code analysis. The article first outlines these three purposes and shows how frameworks such as Android's ButterKnife, Retrofit, and various SSH back‑end libraries rely heavily on annotations.

It then explains how to define a custom annotation, illustrating the use of meta‑annotations like @Target, @Retention, @Documented, and @Inherited. An example definition of an @OnClick annotation is provided:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OnClick {
    int value() default 0;
}

The article describes the allowed element types (e.g., TYPE, FIELD, METHOD) and the restrictions on annotation members (primitive types, String, enums). A more complex annotation Book is also shown, demonstrating default values and enum usage.

To use the annotation, the author builds a miniature ButterKnife‑like processor that scans an Activity class via reflection. Key methods include:

public static final void bindView(final Activity activity) {
    traversalMethod(activity);
    traversalField(activity);
}
private static void traversalMethod(final Activity activity) {
    Method[] methodArray = getObjectMethodArray(activity);
    for (final Method method : methodArray) {
        if (isAnnotationPresent(method)) {
            int viewID = getViewID(method);
            setOnClickListenerForControl(activity, method, viewID);
        }
    }
}

Helper methods isAnnotationPresent, getViewID, and setOnClickListenerForControl retrieve the annotation data and attach click listeners to the corresponding views, invoking the annotated method when the view is clicked.

Finally, the article notes that while the example uses reflection (which has performance costs), the real ButterKnife library employs annotation processing at compile time to avoid these overheads, and promises a follow‑up article covering that approach. A GitHub link to the demo project is also provided.

AndroidReflectionannotationstutorialButterKnife
Java Captain
Written by

Java Captain

Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.