干涸的Java(lambda函数?)
我用Java编写,基本上测试了一堆东西的节目......干涸的Java(lambda函数?)
对于每一个电话,我需要检查NullPointerExceptions
,StackOverflow
,IndexOutOfBounds
等。 ..
我在我的每一个方法现在这个重复模式:
try {
doSomething();
} catch(NullPointerExceptions npe) {
// prints something
} catch(StackOverflow soe) {
// prints something
} catch(IndexOutOfBounds iob) {
// prints something
}
由于我可以调用doSomething()
(具有不同PARAMS)多次在一个单一的方法,我不能只是throw
的EXC eption备份到主要(因为我需要下一个测试来实际运行)。
我想写一个lambda测试,我可以传递给一个函数,但我不能找到一种方法,用java :(做到这一点
我想这样做:
private void test(Method m, E expectedValue) {
try {
if(!m.run().equals(expectedValue))
System.out.println("FAILED TEST: "+m.name()+". Value was "+m.run()+", should have been "+expectedValue);
} catch() {
// see above
}
}
,你可以在Java中做的最好的是使用一个接口:
interface DoSomething<E extends Comparable<E>> {
E doSomething();
}
然后你test
方法可以是这样的:
private void test(DoSomething<E> m, E expectedValue) {
try {
if(!m.doSomething().equals(expectedValue))
System.out.println("FAILED TEST");
} catch() {
//handle exception
}
}
E
需要延续Comparable<E>
,因为你在呼唤equals
的test
内。
这被称为SAM(单抽象方法)接口。使用SAM类和接口来模拟lambda是Java中常见的事件。我甚至听说过他们叫“SAMbdas”。
编辑:我的解决方案并不一定涉及修改现有的类:
DoSomething foo = new DoSomething<String>() {
public String doSomething() { return "Hello World"; }
};
test(foo, "Hello World");
这可能是这样的:
abstract class Method<R> {
public R run();
}
test(new Method<Result1>() {
public Result1 run() { .... }
}, expectedResult);
如果你想这个自己编写的,而不是JUnit的,你可以使用Reflection调用该方法。
所以,与其说m.run()
你可以使用java.lang.reflect.Method#invoke
:
try { method.invoke(obj, arg1, arg2,...); } catch (Exception e) { // there are several Reflection exceptions you also need to deal with }
Lambda表达式要自己的方式工作到JDK7。如果你想尝试一下,抓住早期试用版本之一甲骨文
http://www.jcp.org/en/jsr/detail?id=335
这么说,我不太明白的问题。你可以添加一个你如何打算使用所有这些方法的例子吗?您的建议方法听起来像是在正确的轨道上,请尝试:
private void test(Method m, Object target, Object[] args, E expectedValue) {
try {
if(!m.invoke(target, args).equals(expectedValue))
System.out.println("FAILED TEST: "+m.name()+". Value was "+m.run()+", should have been "+expectedValue);
} catch() {
// see above
}
}
虽然Gus Bosman是正确的。像JUnit这样的单元测试框架可能会有所帮助。
是...但这需要在多台机器上工作,不只是我的... – sethvargo 2011-03-27 17:35:13
JUnit不是专门为您的机器提供。例如,我也使用它 – RoflcoptrException 2011-03-27 17:39:33
不......我不能使用JUnit,但我也不能使用预发布的Java,因为它在多个机器上 – sethvargo 2011-03-27 17:40:39
不幸的是,lambdas还没有出现在java中。但是你可以使用通用的java.util.concurrent.Callable:
private <T> void test(Callable<T> c, T expectedValue) {
try {
if(!c.call().equals(expectedValue))
System.out.println("FAILED TEST: "+c+". Value was "+c.call()+", should have been "+expectedValue);
} catch(Exception ex) {
// see above
}
}
你可以使用JUnit吗?这对你来说或多或少。 – RoflcoptrException 2011-03-27 17:25:53
不,JUnit在这种情况下是不可行的,否则我会使用它... – sethvargo 2011-03-27 17:30:04
我不明白这个问题。也不明白为什么JUnit不适合。 – Bozho 2011-03-27 17:32:46