2

我是 Java 注释的忠实拥护者,但每次我想自己制作时都必须包含 Google 的ReflectionsScannotations ,这让我很头疼。

在没有容器或类似工具的帮助下,我无法找到任何关于 Java 能够自动扫描注释并适当使用它们的文档。

问题:我是否遗漏了一些关于 Java 的基本知识,或者注解的设计总是需要手动扫描和检查?是否有一些处理注释的内置方法?

进一步澄清

我希望能够以编程方式更多地处理 Java 中的注释。例如,假设您想构建 a Listof Cars。为此,您使用可以为您填充列表的类来注释列表。例如:

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

在此示例中,CarMakerJava 接近注释,Java 达成交易并询问他们想要提供多少辆汽车。然后由CarMaker注释/类为他们提供要包含的汽车的列表。这可能是所有带有@CarType注释的类和一个Car接口。

另一种看待它的方式是,如果你知道你想要构建这样的东西:List<Car> cars,你可以用 注释它@ListMaker<Car>。这ListMaker是Java内置的东西。它查找所有用 注释的类@CarType,并相应地填充列表。

4

4 回答 4

4

您可以创建自己的注释并将它们应用到您自己的类中。

如果您指定在运行时可检测到注释,则可以使用反射轻松处理它。

例如,您可以使用类似这样的方法来打印已用Funky注释标记的类中每个字段的名称:

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

声明Funky注释的代码如下所示:

package org.foo.annotations;

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

这是一个使用注解的类:

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;
}

这里有更多关于 Annotations 的阅读

以下是上面使用的类的 javadocs:


我正在尝试了解您的汽车示例,但我不确定我是否遵循您的要求。

如果您有一个对象列表(Jaguar、Porche、Ferrari、Kia),这些对象扩展 Car 并标有各种与汽车相关的注释,您可以创建一个基于注释过滤列表的对象。

代码可能如下所示:

@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
}

您可以实现一个AnnotationFilter类,从列表中删除没有特定注释的汽车。

它可能看起来像这样:

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

那是你想做的吗?

如果是这样,那绝对可以做到。

AnnotationFilter 的实现可能如下所示:

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;
    }
}

如果这不是你所追求的,一个具体的例子会很有帮助。

于 2012-08-14T03:48:37.397 回答
1

Java 没有内置任何东西,这就是 Reflections 出现的原因。没有什么像你所说的那样特别。

于 2012-08-14T04:22:12.830 回答
0

注释只是标记类元素的一种方式;如何解释这些注释取决于定义这些注释的代码。

是否有一些处理注释的内置方法?

注释以多种不同的方式使用,以至于很难想出一些“内置方式”来处理它们。有些源代码级别的注释(例如@Override@Deprecated)根本不影响代码的行为。然后是运行时注释,它们通常非常特定于某个库,例如。JAXB 的绑定注解仅在 a 中有意义,JAXBContext而 Spring 的自动装配注解仅在ApplicationContext. Java 怎么会仅仅通过查看使用它们的类就知道如何处理这些注释?

于 2012-08-14T04:10:25.280 回答
0

用户定义的注释:我们将看到如何注释我们在日常生活中可能遇到的对象。想象一下,我们要将对象信息持久化到一个文件中。一个名为 Persistable 的注解可用于此目的。重要的是我们要提及存储信息的文件。我们可以在 Annotation 本身的声明中拥有一个名为 fileName 的属性。Persistable Annotation 的定义如下:

Persistable.java

@Target({ElementType.FIELD, ElementType.LOCAL_VARIABLE})
    public @interface Persistable
    {
        String fileName();
    }
于 2012-08-14T04:07:15.563 回答