Java 我们如何为每个断言执行一个测试?
嗨,我一直想知道如何在断言中放入整个代码块 例如,我有一个数组,我想对数组的每个值进行断言。这就是我的代码的样子:Java 我们如何为每个断言执行一个测试?,java,assert,Java,Assert,嗨,我一直想知道如何在断言中放入整个代码块 例如,我有一个数组,我想对数组的每个值进行断言。这就是我的代码的样子: for (int value : values) { assert Within(value, x, y); } 当然,如果我运行程序时没有关闭断言的-ea,那么循环仍然存在 我想知道如何将整个循环放入断言语句中 编辑: argh dang Java有时真的太死板了,我最终做了如下功能性的事情: assert Every(value, new F1<Boolean,
for (int value : values) {
assert Within(value, x, y);
}
当然,如果我运行程序时没有关闭断言的-ea
,那么循环仍然存在
我想知道如何将整个循环放入断言语句中
编辑:
argh dang Java有时真的太死板了,我最终做了如下功能性的事情:
assert Every(value, new F1<Boolean, Integer>() {
Boolean Call(Integer value) {
return Within(value, 0, 255);
}
});
assert Every(值,新的F1(){
布尔调用(整数值){
返回范围(值0,255);
}
});
这真的是个问题吗?据我所知,Java编译器和JVM忽略等待循环(空循环)。因此,从我的观点来看,不管整个块是否被断言(最终的二进制应该是相同的(没有任何循环))
编辑: 这就是测试代码的外观,以确保使用HotSpot
public static void main(String args[]) {
int[] values = new int[10000];
for (int i = 0; i < 1000; i++) {
long a = System.nanoTime();
for (int value : values);
long b = System.nanoTime();
System.out.println(b - a);
}
}
publicstaticvoidmain(字符串参数[]){
int[]值=新的int[10000];
对于(int i=0;i<1000;i++){
long a=System.nanoTime();
for(int值:值);
long b=System.nanoTime();
系统输出打印LN(b-a);
}
}
您可以使用
public boolean check(int... values) {
for (int value : values)
if(!Within(value, x, y)) return false;
return true;
}
assert check(values);
另一种方法是,如果有大量检查,则测试断言
boolean assertEnabled = false;
assert assertEnabled = true;
if (assertEnabled) {
// do lots of checks
}
将for循环提取到一个布尔方法中,并对其返回值进行断言。只需创建一个检查数组所有元素的方法:
assert allWithin(values, x, y);
...
private boolean allWithin(int[] values, int x, int y) {
for (int value : values) {
if (!within(value, x, y)) {
return false;
}
}
return true;
}
自Java 8以来,您可以选择为此使用流:
assert values.stream().allMatch(value -> within(value, x, y));
(如果
values
在您的示例中是一个数组,请使用Arrays.stream(values)
来代替。)Hmm,我已经想到了这一点,但是对于一个简单的断言来说,这不是太多样板代码了吗?它是6行还是3行。这取决于您希望避免循环的程度。当然,如果断言被关闭,我们必须避免该循环!这不是因为(value,x,y);中(int-value:values)断言的行数实际上是一行,而是更多的概念性膨胀。对于每个断言来说都不是那么罕见。。因此,如果我的类有5个方法需要这种类型的断言,这不意味着我必须创建5个额外的方法,并将它们命名为check1、check2、check3、check4、check5?如果您不关心哪一个失败,那么可以是check1&&check2&&check3&&check4&&check5。我认为这不是真的。我测量并。。它证明了我是对的(至少在我的机器上是这样)。因此JVM不会忽略空循环,我将尝试查找一些文章。您是否多次尝试重复代码。有可能在“热点”重新编译后删除了循环…不会有任何错误。我已经测试过几次了,差别很大。测试代码:。测试后的结果是什么?必须在循环中运行测试代码,以确保使用hotspot。重复运行程序只会导致每次运行程序时生成未优化的字节码。但是如果测试代码在循环中,hotspot将在多次迭代后意识到程序的一部分被重复调用,因此应该进行优化(循环将被忽略)。