例如,我想为目标参数创建注解@Out。然后我会以某种方式使用编译器检查函数返回之前是否设置了参数值。这可能吗?
还考虑了一个@Immutable 注释,它不允许调用任何未用@Const 注释的方法或访问任何公共(public)字段。 (编译时间和可能的运行时间?)
到目前为止我有这个:
//I'm assuming Class retention is a subset of Runtime retention
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Out
{
//no idea what to go in here.
}
这是另一个注解。同样,我没有完整的定义:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Immutable
{
}
我想我可以开始设计一种策略,在运行时使用反射来实现它,但我想指示编译器或预处理器为我检查这些东西,这样我的注释就会有零开销。
这是您认为“如果可以做到,它早就在那里,如果是,我在哪里可以捕获它”的事情之一。
编辑:在进一步思考@Const 和@Immutable 并记住java 按值将指针传递给对象之后,我扩展了定义@Const,去掉了@Immutable,修改了@Out的定义,如下:
/**
* When Applied to a method, ensures the method doesn't change in any
* way the state of the object used to invoke it, i.e., all the fields
* of the object must remain the same, and no field may be returned,
* unless the field itself is marked as {@code @Const}. A method
* annotated with {@code @Const} can only invoke other {@code @Const}
* methods of its class, can only use the class's fields to invoke
* {@code @Const} methods of the fields classes and can only pass fields
* as parameters to methods that annotate that formal parameter as
* {@code @Const}.
*
* When applied to a formal parameter, ensures the method will not
* modify the value referenced by the formal parameter. A formal
* parameter annotated as {@code @Const} will not be aliased inside the
* body of the method. The method is not allowed to invoke another
* method and pass the annotated parameter, save if the other method
* also annotates the formal parameter as {@code @Const}. The method is
* not allowed to use the parameter to invoke any of its type's methods,
* unless the method being invoked is also annotated as {@code @Const}
*
* When applied to a field, ensures the field cannot be aliased and that
* no code can alter the state of that field, either from inside the
* class that owns the field or from outside it. Any constructor in any
* derived class is allowed to set the value of the field and invoke any
* methods using it. As for methods, only those annotated as
* {@code @Const} may be invoked using the field. The field may only be
* passed as a parameter to a method if the method annotates the
* corresponding formal parameter as {@code @Const}
*
* When applied to a local variable, ensures neither the block where the
* variable is declared or any nested block will alter the value of that
* local variable. The local variable may be defined only once, at any
* point where it is in scope. Only methods annotated as
* {@code @Const} may be invoked using this variable, and the variable
* may only be passed as a parameter to another method if said method
* annotates its corresponding formal parameter as {@code @Const}
*
*/
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD,
ElementType.LOCAL_VARIABLE})
@Inherited
public @interface Const
{
}
现在 @Out:
/**
* The formal parameter annotated with {@code @Out} must be undefined in
* the scope of the caller, and it's the responsibility of the method to
* define it. If allowNull is true, the parameter can be explicitly set
* to null in the body of the method.
*/
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.PARAMETER)
public @interface Out
{
boolean allowNull() default false;
}
编辑: 我正在尝试将其实现为 eclipse 插件,但我完全无法阅读手册。我编写了一个插件,其中包含用于访问 AST 和访问方法和字段的基本逻辑。然后我做了一堆我的插件应该检测到的虚拟注释,然后我尝试打印结果,但我什至不确定会发生什么。我的插件是一个“增量构建”插件。这是它的代码,如果有人可以看一下并向我解释一些事情。我完全迷失在这个 API 中。
最佳答案
javac 编译器支持用户可定义的插件,称为注解处理器,可以完全满足您的需求。您可以将注释视为语言扩展。
定义 public @interface Immutable { ... } 定义了语法:您可以在程序中编写的 @Immutable 注解。注释处理器(编译器插件)定义语义:它强制执行语义规则并在您的程序违反规则时发出编译器警告。
一个使编写此类注释处理器变得容易的框架是 Checker Framework ,它包含注释的定义,例如 @NonNull 和 @Immutable。这里有两个关于如何使用 Checker Framework 来验证代码的教程:tutorial 1 , tutorial 2 .
在每个声明(例如类、字段、方法和方法参数)上调用普通 Java 注释处理,普通 Java 不允许注释处理器访问程序的完整 AST。您可以将 Checker Framework 视为扩展 Java 注释处理功能的库。它使您可以访问每个类的完整 AST,并允许您为程序中的每个语句定义规则。因此,当语句调用 @Immutable 对象上的非 @Const 方法时,您的注释处理器可以发出警告。
您的注释处理器应该是模块化的,一次处理一个类。注解处理器可以访问当前类的 AST,以及它使用的所有类的签名,包括注解。注释处理会为您提供该信息(但不会一次性提供给整个项目的 AST)。
关于java - 我可以使用 Java 注释来定义编译时检查吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36538133/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h