java deprecated 注释,使用注释方法时使java编译器发出警告(如@deprecated)

Let's say I define a custom annotation called @Unsafe.

I'd like to provide an annotation processor which will detect references to methods annotated with @Unsafe and print a warning.

For example, given this code ...

public class Foo {

@Unsafe

public void doSomething() { ... }

}

public class Bar {

public static void main(String[] args) {

new Foo().doSomething();

}

}

... I want the compiler to print something like:

WARN > Bar.java, line 3 : Call to Unsafe API - Foo.doSomething()

It is very similar in spirit to @Deprecated, but my annotation is communicating something different, so I can't use @Deprecated directly. Is there a way to achieve this with an annotation processor? The annotation processor API seems to be more focused on the entities applying the annotations (Foo.java in my example) than entities which reference annotated members.

This question provides a technique to achieve it as a separate build step using ASM. But I'm wondering if I can do it in a more natural way with javac & annotation processing?

解决方案

I think I could have technically achieved my goal using the response from @mernst, so I appreciate the suggestion. However, I found another route that worked better for me as I'm working on a commercial product and cannot incoporate the Checker Framework (its GPL license is incompatible with ours).

In my solution, I use my own "standard" java annotation processor to build a listing of all the methods annotated with @Unsafe.

Then, I developed a javac plugin. The Plugin API makes it easy to find every invocation of any method in the AST. By using some tips from this question, I was able to determine the class and method name from the MethodInvocationTree AST node. Then I compare those method invocations with the earlier "listing" I created containing methods annotated with @Unsafe and issue warnings where required.

Here is an abbreviated version of my javac Plugin.

import javax.lang.model.element.Element;

import javax.lang.model.element.TypeElement;

import com.sun.source.tree.MethodInvocationTree;

import com.sun.source.util.JavacTask;

import com.sun.source.util.Plugin;

import com.sun.source.util.TaskEvent;

import com.sun.source.util.TaskEvent.Kind;

import com.sun.tools.javac.tree.JCTree;

import com.sun.tools.javac.tree.TreeInfo;

import com.sun.source.util.TaskListener;

import com.sun.source.util.TreeScanner;

public class UnsafePlugin implements Plugin, TaskListener {

@Override

public String getName() {

return "UnsafePlugin";

}

@Override

public void init(JavacTask task, String... args) {

task.addTaskListener(this);

}

@Override

public void finished(TaskEvent taskEvt) {

if (taskEvt.getKind() == Kind.ANALYZE) {

taskEvt.getCompilationUnit().accept(new TreeScanner() {

@Override

public Void visitMethodInvocation(MethodInvocationTree methodInv, Void v) {

Element method = TreeInfo.symbol((JCTree) methodInv.getMethodSelect());

TypeElement invokedClass = (TypeElement) method.getEnclosingElement();

String className = invokedClass.toString();

String methodName = methodInv.getMethodSelect().toString().replaceAll(".*\\.", "");

System.out.println("Method Invocation: " + className + " : " + methodName);

return super.visitMethodInvocation(methodInv, v);

}

}, null);

}

}

@Override

public void started(TaskEvent taskEvt) {

}

}

Note - in order for the javac plugin to be invoked, you must provide arguments on the command line:

javac -processorpath build/unsafe-plugin.jar -Xplugin:UnsafePlugin

Also, you must have a file META-INF/services/com.sun.source.util.Plugin in unsafe-plugin.jar containing the fully qualified name of the plugin:

com.unsafetest.javac.UnsafePlugin

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值