Skip to content
CMO & CTO
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

  • Digital Experience
    • Experience Strategy
    • Experience-Driven Commerce
    • Multi-Channel Experience
    • Personalization & Targeting
    • SEO & Performance
    • User Journey & Behavior
  • Marketing Technologies
    • Analytics & Measurement
    • Content Management Systems
    • Customer Data Platforms
    • Digital Asset Management
    • Marketing Automation
    • MarTech Stack & Strategy
    • Technology Buying & ROI
  • Software Engineering
    • Software Engineering
    • Software Architecture
    • General Software
    • Development Practices
    • Productivity & Workflow
    • Code
    • Engineering Management
    • Business of Software
    • Code
    • Digital Transformation
    • Systems Thinking
    • Technical Implementation
  • About
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

Understanding Java Annotations

Posted on July 10, 2007 By Luis Fernandez

Java annotations feel like sticky notes you can attach to code without changing what the method or class does.

What are Java annotations

They are metadata baked right into the source. Think of @Override, @Deprecated, or the JUnit 4 @Test you have likely seen this week. The compiler and tools read them. Your logic stays clean.

Why they matter for readability

Before annotations we stuffed meaning in comments or in cryptic naming. Now we can mark intent with a small tag that is both human friendly and machine friendly. That mix keeps code talkative without extra noise.

Built in sets you should know

Java 5 gave us core ones. The big three are @Override for method overrides, @Deprecated to flag code on the way out, and @SuppressWarnings to calm the compiler. You also get meta annotations like @Retention and @Target that control where and how long an annotation lives.

A tiny example with JUnit 4

This is the classic test style many teams use now. No extends TestCase, just tags.

import org.junit.Test;
import static org.junit.Assert.*;

public class GreetingTest {

    @Test
    public void saysHello() {
        String msg = new Greeting().hello("Ada");
        assertEquals("Hello Ada", msg);
    }
}

Writing your own

You can declare annotations just like interfaces. Here is a simple @Audit tag that we can keep at runtime so tools or a security proxy can read it with reflection.

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Audit {
    String value();
    boolean enabled() default true;
}

Using it feels natural.

@Audit("payments")
public class BillingService {

    @Audit(value = "charge", enabled = true)
    public Receipt charge(Card card, Money amount) {
        // ...
    }
}

Reading annotations with reflection

At runtime you can grab that metadata. This snippet scans a class and prints methods that carry our tag.

for (Method m : BillingService.class.getDeclaredMethods()) {
    Audit audit = m.getAnnotation(Audit.class);
    if (audit != null && audit.enabled()) {
        System.out.println("Audited: " + m.getName() + " area=" + audit.value());
    }
}

Compile time processing in the toolbox

If you want code generation or checks during compile time, you can use apt from JDK 5 or the new javax.annotation.processing in JDK 6. NetBeans and Eclipse Europa both wire it in. Libraries like JPA and EJB 3 ride on the same idea.

Pitfalls and simple rules

Do not turn code into an annotation salad. If everything has a tag, nothing stands out. Keep business rules in code. Use annotations for glue, wiring, or flags that tools and frameworks consume. Prefer clear defaults so a class reads well even without the surrounding magic.

When to skip them

If a tag hides real flow or hides a side effect, stop and write plain code. If a newcomer cannot guess behavior from the class body, you went too far. Aim for that sweet spot where the annotation tells intent and the code tells the story.

Tooling right now

Eclipse Europa indexes annotations fast and shows them in the outline, which makes browsing smoother. NetBeans has solid support as well, and the debugger keeps annotation values handy. On servers, GlassFish and JBoss pick up JPA and EJB tags with no xml. That alone is a relief.

Quick cheat sheet

Memorize three pairs. @Retention with SOURCE CLASS or RUNTIME. @Target with TYPE METHOD FIELD and friends. And @Inherited which lets subclasses see class level tags.

From xml to annotations

Many teams are moving JPA mappings into the code. Less bouncing between files, fewer typos. Here is a tiny entity that shows the flavor.

import javax.persistence.*;

@Entity
@Table(name = "greeting")
public class Greeting {

    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false)
    private String message;

    // getters and setters
}

It reads like a snapshot of the table. Most days this beats a pile of xml because your eyes stay in one place. For large mapping quirks you can still mix in orm xml.

Performance and class loading

Annotations sit in the class file, and reading them with reflection is cheap for occasional checks. A tight loop that calls getAnnotation on every hit is not a great idea. Cache results per class. That pattern keeps startup tidy and makes hot paths happy.

Naming tips

Pick names that read like plain English. @Audit and @Transactional say a lot. @XyZ is a mystery. Avoid boolean names that read backwards.

When you need xml

Some shops still prefer deployment descriptors for ops overrides. Keep both doors open. An annotation can define a sane base while an xml file adjusts a value for a staging box. Pick the tool that matches the change cycle.

APT and processors

If you enjoy meta work, write a small processor. With JDK 6 you extend AbstractProcessor and handle annotations in a round. You can generate sources, fail a build on missing tags, or write an index file that your app reads at startup.

Share your take in the comments.

What tag helped your team the most

Code Development Practices Software Engineering coding-practicesjavaspring

Post navigation

Previous post
Next post
  • Digital Experience (94)
    • Experience Strategy (19)
    • Experience-Driven Commerce (5)
    • Multi-Channel Experience (9)
    • Personalization & Targeting (21)
    • SEO & Performance (10)
  • Marketing Technologies (92)
    • Analytics & Measurement (14)
    • Content Management Systems (45)
    • Customer Data Platforms (4)
    • Digital Asset Management (8)
    • Marketing Automation (6)
    • MarTech Stack & Strategy (10)
    • Technology Buying & ROI (3)
  • Software Engineering (310)
    • Business of Software (20)
    • Code (30)
    • Development Practices (52)
    • Digital Transformation (21)
    • Engineering Management (25)
    • General Software (82)
    • Productivity & Workflow (30)
    • Software Architecture (85)
    • Technical Implementation (23)
  • 2025 (12)
  • 2024 (8)
  • 2023 (18)
  • 2022 (13)
  • 2021 (3)
  • 2020 (8)
  • 2019 (8)
  • 2018 (23)
  • 2017 (17)
  • 2016 (40)
  • 2015 (37)
  • 2014 (25)
  • 2013 (28)
  • 2012 (24)
  • 2011 (30)
  • 2010 (42)
  • 2009 (25)
  • 2008 (13)
  • 2007 (33)
  • 2006 (26)

Ab Testing Adobe Adobe Analytics Adobe Target AEM agile-methodologies Analytics architecture-patterns CDP CMS coding-practices content-marketing Content Supply Chain Conversion Optimization Core Web Vitals customer-education Customer Data Platform Customer Experience Customer Journey DAM Data Layer Data Unification documentation DXP Individualization java Martech metrics mobile-development Mobile First Multichannel Omnichannel Personalization product-strategy project-management Responsive Design Search Engine Optimization Segmentation seo spring Targeting Tracking user-experience User Journey web-development

©2025 CMO & CTO | WordPress Theme by SuperbThemes