2

I'm a huge fan of Java's annotations, but find it a pain in the neck to have to include Google's Reflections or Scannotations every time I want to make my own.

I haven't been able to find any documentation about Java being able to automatically scan for annotations & use them appropriately, without the help of a container or alike.

Question: Have I missed something fundamental about Java, or were annotations always designed such that manual scanning & checking is required? Is there some built-in way of handling annotations?

To clarify further

I'd like to be able to approach annotations in Java a little more programatically. For instance, say you wanted to build a List of Cars. To do this, you annotate the list with a class that can populate the list for you. For instance:

@CarMaker
List<Car> cars = new List<Car>();

In this example, the CarMaker annotation is approached by Java, who strikes a deal and asks them how many cars they want to provide. It's up to the CarMaker annotation/class to then provide them with a list of which cars to include. This could be all classes with @CarType annotations, and a Car interface.

Another way of looking at it, is that if you know you want to build something like this: List<Car> cars, you could annotate it with @ListMaker<Car>. The ListMaker is something built into Java. It looks for all classes annotated with @CarType, and populates the list accordingly.

5
  • Annotations are a special kind of class, and just like every other class, they must be imported to be used. Commented Aug 14, 2012 at 3:42
  • Your question is rather unclear. What do you mean by "Java automatically scanning for annotations and using them"? Your use case looks vaguely like dependency injection. If you want that, check out the Spring framework or something similar. But this is not the "job" of Java. If you want to understand the purpose and scope of annotations better, check the language specification. Commented Aug 14, 2012 at 3:48
  • Based on your description, List<Car> cars = new ArrayList<Car>() would be a list of Car annotations. That doesn't make much sense. Commented Aug 14, 2012 at 4:44
  • Clarrified it again. Thanks :P Commented Aug 14, 2012 at 4:45
  • I could be wrong, but I think you're describing a situation where you would use a CarListFactory object to create a list of classes that have the CarType annotation (or a CarType annotation with a specific value ["BMW" for example]). Still, if you're using annotations your list will contain class objects, NOT Car objects. Annotations are applied to classes, not objects (instances of classes). Commented Aug 14, 2012 at 4:49

4 Answers 4

4

You can create your own annotations and apply them to your own classes.

If you specify that an annotation is detectable at runtime, you can process it easily with reflection.

For example, you could use something like this to print the name of each field in a class that has been marked with the Funky annotation:

for (Field someField : AnnotatedClass.getClass().getDeclaredFields()) {
    if (someField.isAnnotationPresent(Funky.class)) {
        System.out.println("This field is funky: " + someField.getName());
    }
}

The code to declare the Funky annotation would look something like this:

package org.foo.annotations;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Funky { }

Here's a class that uses the annotation:

package org.foo.examples;

import org.foo.annotations.Funky;

public class AnnotatedClass {
    @Funky
    private  String   funkyString;
    private  String   nonFunkyString;
    @Funky
    private  Integer  funkyInteger;
    private  Integer  nonFunkyInteger;
}

Here's some more reading on Annotations.

Here are the javadocs for the classes used above:


I'm trying to understand your car example, but I'm not sure I follow what you want.

If you had a list of objects (Jaguar, Porche, Ferrari, Kia) that extend Car and are marked with various car-related annotations, you could create an object that filters the list based on annotations.

The code might look like this:

@WorldsFinestMotorCar
class Jaguar extends Car {
    // blah blah
}

@BoringCar
class Porche extends Car {
    // blah blah
} 

@BoringCar
class Ferrari extends Car {
    // blah blah
}

@IncredibleCar
class Kia extends Car {
    // blah blah
}

You could implement an AnnotationFilter class that removes cars from the list that do not have a certain annotation.

It might look something like this:

List<Car> carList = getListOfRandomCars();
AnnotationFilter<Car> annoFilter = new AnnotationFilter<Car>(BoringCar.class);
List<Car> boringCars = annoFilter.filter(carList);

Is that what you want to do?

If so, it can definitely be done.

The implementation for AnnotationFilter might look something like this:

public class AnnotationFilter<T> {
    private Class filterAnno;

    public AnnotationFilter(Class a) {
        filterAnno = a;
    }

    public List<T> filter(List<T> inputList) {
        if (inputList == null || inputList.isEmpty()) {
            return inputList;
        }
        List<T> filteredList = new ArrayList<T>();
        for (T someT : inputList) {
            if (someT.getClass().isAnnotationPresent(filterAnno)) {
                filteredList.add(someT);
            }
        }
        return filteredList;
    }
}

If that's not what you're after, a specific example would be helpful.

Sign up to request clarification or add additional context in comments.

4 Comments

This doesn't entirely answer what I was looking for, but it's the closest. What I was hoping to get was a bit vaguer than what you've said, but it gives me an understanding of how annotations are at least approached.
@TehHippo - I don't quite follow your CarMaker example. Maybe if you explain exactly what you mean, we can give a better answer. You could certainly have a CarFactory class that uses annotations and reflection to create a list that contains an instance of each class with the Car annotation. Is that what you're after?
@TehHippo - You could probably implement your own AnnotatedArrayList class (that extends ArrayList) and is capable of returing a list of classes with a given annotation. However, this would simply be a list of class objects. I don't see how it would be useful. Also... Your CarMaker example code actually declares a List of Car Annotations , which really makes no sense.
@TehHippo - I updated my answer with an attempt to understand your car example some more.
1

Java haven't got anything built in as such, which is why Reflections came about. Nothing built in that's as particular as what you're saying..

Comments

0

User-defined Annotations: we shall see how to annotate objects that we may come across in day-to-day life. Imagine that we want to persistent object information to a file. An Annotation called Persistable can be used for this purpose. An important thing is that we want to mention the file in which the information will get stored. We can have a property called fileName within the declaration of Annotation itself. The definition of the Persistable Annotation is given below,

Persistable.java

@Target({ElementType.FIELD, ElementType.LOCAL_VARIABLE})
    public @interface Persistable
    {
        String fileName();
    }

Comments

0

Annotations are just a way of tagging elements of a class; how these annotations are interpreted is up to the code that defines these annotations.

Is there some built-in way of handling annotations?

Annotations are used in so many different ways that it would be difficult to come up with a few "built-in ways" of handling them. There are source-level annotations (such as @Override and @Deprecated) that do not affect the behaviour of the code at all. Then there are runtime annotations that are usually very specific to a certain library, for eg. JAXB's binding annotations only make sense within a JAXBContext and Spring's autowiring annotations only make sense within an ApplicationContext. How would Java know what to do with these annotations simply by looking at a class which uses them?

3 Comments

What I was saying with things like JAXB & Spring's autowiring, reflections & scannotations, is that it seems annoying to not have some basic built in methods. I think I've got a different view on how annotations should be approached. Appreciate your comments, but I was looking at whether there were some built-in ways of handling them, without being technical.
"How would Java know what to do with these annotations simply by looking at a class which uses them?" Correct me if I'm wrong, but Java doesn't have to do anything with them, someone has to write code that will reflectively look for occurrences of those annotations and do something with them. How is this different than @Override and @Deprecated?
@Shakedown: I think we agree that Java doesn't do anything with them, the question was aimed at the OP who was looking for a built-in way to handle these.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.