Java中是否存在类似于Callable
接口的接口,它可以接受其调用方法的参数?
像这样:
public interface MyCallable<V> {
V call(String s) throws Exception;
}
如果已经存在我可以使用的东西,我宁愿避免创建新类型。或者是否有更好的策略让多个客户端实现并插入可调用的例程?
答案 0 :(得分:41)
从Java 8开始,the java.util.function
package中有一整套类似函数的接口。你特别要求的只是Function
。
在Java 8之前,没有通用的内置接口,但有些库提供了它。
例如,Guava的the Function<F,T>
interface方法为T apply(F input)
。它还在几个地方制作heavy use of that interface。
答案 1 :(得分:9)
起初它认为这是通过接口完成的,但后来我发现它应该使用抽象类来完成。
我已经这样解决了:编辑:最近我只是用这个:
public static abstract class callback1<T>{
public abstract void run(T value);
}
public static abstract class callback2<T,J>{
public abstract void run(T value,J value2);
}
public static abstract class callback3<T,J,Z>{
public abstract void run(T value,J value2,Z value3);
}
public static abstract class callbackret1<R,T>{
public abstract R run(T value);
}
public static abstract class callbackret2<R,T,J>{
public abstract R run(T value,J value2);
}
public static abstract class callbackret3<R,T,J,Z>{
public abstract R run(T value,J value2,Z value3);
}
<强> CallBack.java 强>
public abstract class CallBack<TRet,TArg> {
public abstract TRet call(TArg val);
}
定义方法:
class Sample2
{
CallBack<Void,String> cb;
void callcb(CallBack<Void,String> CB)
{
cb=CB; //save the callback
cb.call("yes!"); // call the callback
}
}
使用方法:
sample2.callcb(new CallBack<Void,String>(){
@Override
public Void call(String val) {
// TODO Auto-generated method stub
return null;
}
});
两个参数示例: CallBack2.java
public abstract class CallBack2<TRet,TArg1,TArg2> {
public abstract TRet call(TArg1 val1,TArg2 val2);
}
请注意,当您使用Void返回类型时,您必须使用return null; 所以这里有一个修改的变体,因为通常回调不会返回任何值。
返回类型为void: SimpleCallBack.java
public abstract class SimpleCallBack<TArg> {
public abstract void call(TArg val);
}
void as return type 2 args: SimpleCallBack2.java
public abstract class SimpleCallBack<TArg1,TArg2> {
public abstract void call(TArg1 val1,TArg2 val2);
}
接口对此没用。
接口允许多种类型匹配相同的类型。通过拥有一组共享的预定义函数。
抽象类允许稍后完成其中的空函数。在扩展或实例化。
答案 2 :(得分:5)
我最近有同样的要求。正如其他人所解释的那样,许多lib确实提供了“功能”方法,但这些方法并没有引发异常。
一些项目提供解决方案的示例是 RxJava 库,其中使用 ActionX 等接口,其中'X'为0 ... N, 调用方法的参数数量。他们甚至有一个varargs界面, ActionN 。
我目前的方法是使用简单的通用接口:
public interface Invoke<T,V> {
public T call(V data) throws Exception;
// public T call(V... data) throws Exception;
}
在我的情况下,第二种方法更可取,但它在我的IDE中表现出可怕的“类型安全:通过varargs参数数据的潜在堆污染”,这是另一个问题。
我正在研究的另一种方法是使用现有的接口,例如 java.util.concurrent.Callable ,它们不会抛出异常,并且在我的实现中将异常包含在未经检查的异常中。
答案 3 :(得分:1)
答案含糊不清。严格地说,就是“出于与Callable接口相同的目的”,没有。
有类似的课程,根据你的需要,它们可能会或可能不方便。其中一个是SwingWorker。但是,顾名思义,它是为在Swing框架中使用而设计的。它可以用于其他目的,但这将是一个糟糕的设计选择。
我最好的建议是使用扩展库(Jakarta-Commons,Guava等)提供的扩展库,具体取决于您已在系统中使用的库。
答案 4 :(得分:1)
从Java 1.8开始,有一个Supplier<T>
接口。它有一个get()
方法而不是call()
,并且它不会声明抛出任何异常。
答案 5 :(得分:0)
通常不需要参数,因为该方法的构造函数中可以包含任意数量的参数。
final int i = 5;
final String word = "hello";
Future<String> future = service.submit(new Callable<String>() {
public String call() {
return word + i;
}
});
在此示例中,i
和word
已被使用,但您可以“传递”任意数量的参数。
答案 6 :(得分:0)
我遇到了同样的问题。你可以包装任何方法来返回一个可调用的,并执行它的返回值。 即。
main {
Callable<Integer> integerCallable = getIntegerCallable(400);
Future<Integer> future = executor.submit(integerCallable);
}
private Callable<Integer> getIntegerCallable(int n) {
return () -> {
try {
TimeUnit.SECONDS.sleep(n);
return 123;
} catch (InterruptedException e) {
throw new IllegalStateException("task interrupted", e);
}
};
}
答案 7 :(得分:0)
这样定义一个接口:
interface MyFunction<I, O> {
O call(I input);
}
定义方法:
void getOrderData(final Function<JSONArray, Void> func){
...
JSONArray json = getJSONArray();
if(func!=null) func.call(json);
}
用法示例:
//call getOrderData somewhere in your code
getOrderData(new Function<JSONArray, Void>() {
@Override
public Void call(JSONArray input) {
parseJSON(input);
return null;
}
});