pim*_*ttc 74 java javac compiler-warnings
我要做一个丑陋的临时黑客,以便在我们等待修复外部资源时解决阻塞问题.除了用一个可怕的评论和一堆FIXME来标记它之外,我很乐意让编译器抛出明显的警告信息作为提示,所以我们不要忘记把它拿出来.例如,类似于:
[javac] com.foo.Hacky.java:192: warning: FIXME temporary hack to work around library bug, remove me when library is fixed!
Run Code Online (Sandbox Code Playgroud)
有没有办法可以使用我选择的消息引起有意的编译器警告?如果做不到这一点,最简单的事情是添加到代码中以抛出现有警告,可能在违规行的字符串中有一条消息,以便在警告消息中打印出来?
编辑:不推荐的标签似乎没有为我做任何事情:
/**
* @deprecated "Temporary hack to work around remote server quirks"
*/
@Deprecated
private void doSomeHackyStuff() { ... }
Run Code Online (Sandbox Code Playgroud)
在eclipse或sun javac 1.6(从ant脚本运行)中没有编译器或运行时错误,它肯定正在执行该函数.
bar*_*jak 85
我认为将由编译器处理的自定义注释是解决方案.我经常编写自定义注释来在运行时执行操作,但我从未尝试在编译时使用它们.所以,我只能指出你可能需要的工具:
我不知道这个解决方案是否真的可行.当我找到一些时间时,我会尝试自己实现它.
编辑
我成功实施了我的解决方案 作为奖励,我使用java的服务提供商工具来简化其使用.实际上,我的解决方案是一个包含2个类的jar:自定义注释和注释处理器.要使用它,只需在项目的类路径中添加此jar,并注释您想要的任何内容!这在我的IDE(NetBeans)中正常工作.
注释代码:
package fr.barjak.hack;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.LOCAL_VARIABLE, ElementType.METHOD, ElementType.PACKAGE, ElementType.PARAMETER, ElementType.TYPE})
public @interface Hack {
}
Run Code Online (Sandbox Code Playgroud)
处理器代码:
package fr.barjak.hack_processor;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic.Kind;
@SupportedAnnotationTypes("fr.barjak.hack.Hack")
public class Processor extends AbstractProcessor {
private ProcessingEnvironment env;
@Override
public synchronized void init(ProcessingEnvironment pe) {
this.env = pe;
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (!roundEnv.processingOver()) {
for (TypeElement te : annotations) {
final Set< ? extends Element> elts = roundEnv.getElementsAnnotatedWith(te);
for (Element elt : elts) {
env.getMessager().printMessage(Kind.WARNING,
String.format("%s : thou shalt not hack %s", roundEnv.getRootElements(), elt),
elt);
}
}
}
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
要将生成的jar作为服务提供者启用,请在jar中添加该文件META-INF/services/javax.annotation.processing.Processor
.此文件是一个必须包含以下文本的acsii文件:
fr.barjak.hack_processor.Processor
Run Code Online (Sandbox Code Playgroud)
Kev*_*Day 37
我见过的一种技术是将其与单元测试联系起来(你做单元测试吧?).基本上,一旦实现外部资源修复,您就会创建一个单元测试失败.然后你评论单元测试,告诉别人一旦问题解决后如何撤消你的粗暴黑客.
这种方法的真正含义是,撤消黑客攻击的触发器是解决核心问题本身的问题.
Luc*_*ein 13
一些快速且不那么脏的方法,可能是使用@SuppressWarnings
带有故意错误String
参数的注释:
@SuppressWarnings("FIXME: this is a hack and should be fixed.")
Run Code Online (Sandbox Code Playgroud)
这将生成警告,因为编译器无法将其识别为要禁止的特定警告:
不支持的@SuppressWarnings("FIXME:这是一个黑客,应该修复.")
WRe*_*ach 12
一个好的黑客应该得到另一个...我通常通过在hacky方法中引入一个未使用的变量来为所描述的目的生成编译器警告,因此:
Run Code Online (Sandbox Code Playgroud)/**
* @deprecated "Temporary hack to work around remote server quirks"
*/
@Deprecated
private void doSomeHackyStuff() {
int FIXMEtemporaryHackToWorkAroundLibraryBugRemoveMeWhenLibraryIsFixed;
...
}
这个未使用的变量将生成一个警告(取决于您的编译器)将看起来像这样:
WARNING: The local variable FIXMEtemporaryHackToWorkAroundLibraryBugRemoveMeWhenLibraryIsFixed is never read.
这个解决方案不如自定义注释好,但它的优点是它不需要提前准备(假设编译器已配置为对未使用的变量发出警告).我建议这种方法只适用于短暂的黑客攻击.对于长期存在的黑客攻击,我认为创建自定义注释的努力是合理的.
我写了一个用注释执行此操作的库:Lightweight Javac @Warning Annotation
用法很简单:
// some code...
@Warning("This method should be refactored")
public void someCodeWhichYouNeedAtTheMomentButYouWantToRefactorItLater() {
// bad stuff going on here...
}
Run Code Online (Sandbox Code Playgroud)
编译器会向您的文本发出警告消息
如何将方法或类标记为@Deprecated?这里的文档.请注意,有@Deprecated和@deprecated - 大写D版本是注释,小写d是javadoc版本.javadoc版本允许您指定一个任意字符串来解释正在发生的事情.但编译器在看到它时不需要发出警告(尽管许多人都这样做).注释应始终引发警告,但我不认为您可以添加解释.
这里更新的是我刚刚测试过的代码:Sample.java包含:
public class Sample {
@Deprecated
public static void foo() {
System.out.println("I am a hack");
}
}
Run Code Online (Sandbox Code Playgroud)
SampleCaller.java包含:
public class SampleCaller{
public static void main(String [] args) {
Sample.foo();
}
}
Run Code Online (Sandbox Code Playgroud)
当我运行"javac Sample.java SampleCaller.java"时,我得到以下输出:
Note: SampleCaller.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Run Code Online (Sandbox Code Playgroud)
我正在使用sun的javac 1.6.如果您想要诚实的善意警告而不仅仅是注释,请使用-Xlint选项.也许这会通过Ant正确渗透.
归档时间: |
|
查看次数: |
29333 次 |
最近记录: |