首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >注释不起作用

注释不起作用
EN

Stack Overflow用户
提问于 2012-07-21 19:07:53
回答 2查看 10.7K关注 0票数 6

我正在编写一个注释,它的目标是使类不可变。这里是处理器的代码:

代码语言:javascript
复制
@SupportedAnnotationTypes("archipel.immutability.IsImmutable")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class IsImmutableProcessor extends AbstractProcessor {

    @Override
    public boolean process(Set<? extends TypeElement> annotations,
            RoundEnvironment roundEnv) {
        for (TypeElement type : annotations) {
            processMustBeImmutable(roundEnv, type);
        }
        return true;
    }

    private void processMustBeImmutable(RoundEnvironment env, TypeElement type) {
        for (Element element : env.getElementsAnnotatedWith(type)) {
            processClass(element);
        }
    }

    private void processClass(Element element) {
        boolean isFinal=false;

        for(Modifier modifier : element.getModifiers()) {
            if (modifier.equals(Modifier.FINAL)) {
                isFinal=true;
                break;
            }
        }

        if (!isFinal) {
            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Class "+element+" is not immutable because it is not final");
        } else {
            for (Element subElement : element.getEnclosedElements()) {
                if (subElement.getKind()==ElementKind.FIELD) {
                    isFinal=false;

                    for(Modifier modifier : subElement.getModifiers()) {
                        if (modifier.equals(Modifier.FINAL)) {
                            isFinal=true;
                            break;
                        }
                    }
                    if (!isFinal) {
                        processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Field "+element+" is not immutable because it is not final");
                    } else {
                        Element superElement = subElement.getEnclosingElement();
                        // TODO
                    }
                }
            }
        }
    }

}

当然,注释本身是微不足道的:

代码语言:javascript
复制
@Inherited
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface IsImmutable {
}

我用Ant脚本编译它:

代码语言:javascript
复制
<project name="immutability" basedir="." default="main">

    <property name="lib.dir" value="lib"/>

    <property name="src.dir" value="src"/>

    <property name="build.dir" value="build"/>
    <property name="classes.dir" value="${build.dir}/classes"/>
    <property name="meta.dir" value="${build.dir}/META-INF"/>
    <property name="jar.dir" value="${build.dir}/jar"/>

    <property name="processor-package"
        value="archipel.immutability" />

    <property name="processor" value="${processor-package}.IsImmutableProcessor"/>

    <path id="classpath">
        <fileset dir="${lib.dir}" includes="**/*.jar"/>
        <fileset dir="${classes.dir}"/>
    </path>

    <target name="clean">
    <delete dir="${build.dir}"/>
    </target>

    <target name="compile" description="Compiles the code.">
        <mkdir dir="${classes.dir}"/>
        <javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath" />
    </target>

    <target name="jar" depends="compile">
        <mkdir dir="${jar.dir}"/>
        <jar destfile="${jar.dir}/${ant.project.name}.jar">
            <fileset dir="${classes.dir}"/>
            <service type="javax.annotation.processing.Processor" provider="archipel.immutability.IsImmutableProcessor"/>
        </jar>
    </target>

    <target name="main" depends="clean,jar"/>

</project>

问题是,一定缺少了一些东西,因为当我尝试使用由结果jar文件提供的结果注释时,什么也不会发生:

代码语言:javascript
复制
@IsImmutable
public class Immut {

    private int toto;

    public int getToto() {
        return toto;
    }

    public void setToto(int toto) {
        this.toto = toto;
    }

    public final static void main(String args[]) {
        Immut truc = new Immut();
        truc.setToto(5);
        truc.setToto(6);
    }

}

显然,这个类不是最终的,类应该在Eclipse中显示一个错误。但事实并非如此。

有什么想法吗?

编辑:我用build.xml构建的jar文件似乎是正确的:它包含类文件,以及包含archipel.immutability.IsImmutableProcessorMETA-INF/services/javax.annotation.processing.Processor文件。我在测试项目中导入这个jar文件,当我在Immut类中使用注释(这只是一个粗略的测试)时,什么都不会发生。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-21 19:24:40

默认情况下,在eclipse中禁用注释处理。为了启用它,您需要打开项目属性,然后再打开1.JavaCompiler ->注释处理:启用注释处理2. Java ->注释处理->工厂路径:添加带有工厂的jar

如果您需要更多信息,请查看:getting started with AP in eclipse

编辑:

看看这个tutorial。它详细解释了如何设置eclipse以使用自定义注释处理器。

注意:当打印错误时,请使用此方法:javax.annotation.processing.Messager.printMessage(Kind, CharSequence, Element),而不是:

javax.annotation.processing.Messager.printMessage(Kind, CharSequence).

来自第一个视图的消息在Problems视图和大多数与源相关的视图中可见,而来自第二个视图的消息仅在ErrorLog视图中可见。

票数 11
EN

Stack Overflow用户

发布于 2012-07-27 13:13:10

也许使用cglib使您的对象不可变是值得的。因为假设您在类中有一个集合,而集合字段是最终的。你也有这个收藏的参考资料。这是否意味着集合不能在teh类之外进行修改?不完全同意。只有当此集合被Collections.unmodifiedCollection方法包装时。或者如果您使用的是番石榴不变集合http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained

重点是--不要试图使用hanle --这只是检查字段是否是最终的--它不会处理所有的场景。使用cglib代理代替spring和hibernate

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11595100

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档