由于Java的assert
关键字在Android上是fundamentally broken,我即将实现一个断言类,该类可以配置为检查发布版本中的断言。
现在我可以这样做:
MyAssertion.assert(a != 2)
在表达式为false时抛出AssertionException
。但是,如何获取要传递给错误消息的表达式的String表示?
答案 0 :(得分:5)
唯一的方法是在assert
方法中添加String参数:
MyAssertion.assert(a != 2, "a must not be equal to 2");
您作为assert
的输入获得的是真或假,因此您无法从中构建代表性字符串。
否则,您可以像这样实施assert
:
MyAssertion.assertNotEquals(a, 2);
如果失败,你知道这是因为你测试的等于2,你可以建立一个信息性的消息(虽然你不知道具体等于2)。
如果你想以某种方式能够从断言构造一个有意义的消息,我认为可能的唯一方法是构造一个String表达式,要求JavaScript引擎评估它并在表达式求值为{时构建一条消息{1}}。请注意,这会降低很多性能,因为启动JavaScript引擎需要花费大量时间。这可以通过在生产中禁用断言的机制来解决。
以下是一个例子。请注意,我正在使用新的Java 8 Nashorn JavaScript引擎,但这应该适用于较旧的Rhino。
用法示例:
false
这将引发第三个断言:
断言失败:3 == 4&& 'test'=='test'
这个想法是你可以编写任何可以被评估为布尔值的JavaScript友好表达式。占位符int value = 3;
String str = "test";
Assertions.assertTrue("$1 == 3", value);
Assertions.assertTrue("$1 == 3 && $2 == 'test'", value, str);
Assertions.assertTrue("$1 == 4 && $2 == 'test'", value, str);
将替换为方法的参数($i
将替换为第一个参数等)。
这是班级。它可以改进(处理错误条件,如没有足够的参数等),但这应该足以让你开始。
$1
答案 1 :(得分:4)
注释处理可以做到这一点。您可以创建一个注释,例如@InlineAssertExpressions
。然后编写一个解析源文件的处理器并创建一个表示表达式的字符串,并将其添加到对assert方法的调用中,您可以重载该方法以获取可选的String参数。这种方式在性能方面是最佳的,因为内联发生在编译时。注释处理有点被忽略,但我认为这是很有用的。
答案 2 :(得分:2)
(1)使用简单,但难以实施。需要Java 8。您可以使用lambda表达式:
Assert.isTrue(() => a != 2)
在评估失败时,Assert.isTrue方法的实现应重复IDE所做的所有步骤 - (a)发现lambda类的字节码,(b)反编译例如:与JAD,(c)发现可用的来源
(2)使用简单,易于实施,但不能完全满足您的要求。您可以使用CodeStyle规则来检查&强制使用正确的断言。一个regexp将检查没有单参数断言,第二个(使用regexp back refs)将检查代码和文本描述是否相似。
(3)易于使用,易于实现,但依赖于您的构建系统。您可以在项目构建期间自动检查和修复源代码。
E.g。对于Maven构建系统,您可以创建自己的插件来检查和修复流程源阶段的源中的断言用法。
答案 3 :(得分:2)
我认为你无法访问传递给方法调用的内部java表达式。
但是,您可以使用一些表达式语言库并为断言实现执行自定义表达式处理。
以下是一些表达式语言库的列表:
http://java-source.net/open-source/expression-languages
希望有所帮助:)