Java 可调用<;T>;可以传递参数的替换
我有很多代码,每个函数都以相同的方式开始和结束。所以我开始使用Callable来让它更清晰。但是我想做的是以某种方式将“check”对象发送到每个函数(foo/doo/roo),但是调用方法不允许发送参数。有更好的方法吗Java 可调用<;T>;可以传递参数的替换,java,Java,我有很多代码,每个函数都以相同的方式开始和结束。所以我开始使用Callable来让它更清晰。但是我想做的是以某种方式将“check”对象发送到每个函数(foo/doo/roo),但是调用方法不允许发送参数。有更好的方法吗 public void foo(String something, Boolean flag, Object obj) { callSafe(something, flag, () => /*some code capturing obj*/); } publi
public void foo(String something, Boolean flag, Object obj) {
callSafe(something, flag, () => /*some code capturing obj*/);
}
public void doo(String something, Boolean flag) {
callSafe(something, flag, () => /*different code using check*/);
}
public void roo(String something, Boolean flag, Integer id) {
callSafe(something, flag, () => /*some code using check*/);
}
private void callSafe(string something, Boolean flag, Callable<T> c) {
try {
Object check = someFunction(flag, something);
if (check.IsTrue()) {
c.call();
//c.call(check); //What I want to do.
}
} catch(Exception e) {
// handle exception
}
}
public void foo(字符串、布尔标志、对象obj){
callSafe(something,flag,()=>/*一些代码捕获obj*/);
}
公共void doo(字符串、布尔标志){
callSafe(something,flag,()=>/*使用check*/)的不同代码;
}
公共void roo(字符串、布尔标志、整数id){
callSafe(something,flag,()=>/*一些代码使用check*/);
}
私有void callSafe(字符串、布尔标志、可调用c){
试一试{
对象检查=某个函数(标志,某物);
if(检查.IsTrue()){
c、 call();
//c、 打电话(检查);//我想做什么。
}
}捕获(例外e){
//处理异常
}
}
我想我可以只运行“someFunction”两次(一次在可调用函数中运行,一次在实际函数中运行),但函数很慢,我不想这样做
编辑:通过添加一个界面和使用@Eran建议的方法来修复它。界面:
@FunctionalInterface
public interface CheckedFunction<T, R> {
R apply(T t) throws Exception;
}
@FunctionalInterface
public interface ThrowingCheckResultConsumer {
void accept(CheckResult obj) throws MyException;
}
@functioninterface
公共接口检查功能{
R apply(T)抛出异常;
}
但我不确定这是否是一种好的做法。有什么想法吗?首先,我不确定
可调用
是否合适,因为调用
方法返回一个值,您可以忽略该值
您可以使用消费者
,它有一个接受(SomeClass t)
方法
private void callSafe(String something, Boolean flag, Consumer<SomeClass> c) {
try {
SomeClass check = someFunction(flag, something);
if (check.IsTrue()) {
c.accept (check);
}
} catch(Exception e) {
// handle exception
}
}
public void roo(String something, Boolean flag, Integer id) {
callSafe(something, flag, (SomeClass check) -> /*some code using check*/);
}
是的,有更好的办法 您应该研究面向方面的编程。如果您使用的是Spring,那么为您的任务集成Spring的运行时代理应该相当轻松 您将需要创建包装函数的方面,创建标记函数的注释(必须是Spring组件,具有组件接口中的公共方法),配置方面 有关详细信息,请参阅
在Spring的运行时方面,这似乎是一个简单的示例驱动的介绍:。表面上看,您想要一个
消费者:
。。。或者更一般地说:
@FunctionalInterface
public interface ThrowingConsumer<T,E extends Exception> {
void accept(T obj) throws E;
}
或者在你的情况下:
callSafe(something, flag, cr -> doSomethingWith(cr));
。。。及
private void callSafe(String something, Boolean flag, ThrowingCheckResultConsumer consumer) {
try {
SomeClass check = someFunction(flag, something);
if (check.IsTrue()) {
consumer.accept(check);
}
} catch(MyException e) {
// handle exception
}
}
在你的问题中,你抓住了异常。我使用了MyException
,因为广泛地捕捉Exception
通常被认为是不好的风格。只有catchRuntimeException
和您调用的代码声明的选中异常
但是,如果必须,您可以将此代码中的MyException
替换为Exception
有些库提供了选中的*
功能接口。这是一个。Vavr的CheckedConsumer.accept()
抛出Throwable
尝试并找到一个不抛出已检查异常的消费者可能更容易。如果您控制异常,请考虑将它们扩展为<代码>运行时异常< /代码>。或者在您的消费者中捕获它们,然后用运行时异常
重新包装,这对我来说不起作用。当我在两个地方都使用SomeClass时,出现了一个“不兼容类型”错误。@Wolfyaskingstuff您能举一个实际lambda表达式的例子吗?问题可能出在“/*some代码使用check*/”部分。lambda表达式返回一些值,我想这就是给我的答案problems@Wolfyaskingstuff因为在您的示例中,您没有使用您使用的原始Callable
返回的值执行任何操作,所以我假设您不需要返回值。因此lambda不应该返回值。如果需要返回值,请使用函数
界面,而不是使用者
。该函数将无法处理异常。
ThrowingCheckResultConsumer c = cr -> doSomethingWith(cr);
c.accept("");
callSafe(something, flag, cr -> doSomethingWith(cr));
private void callSafe(String something, Boolean flag, ThrowingCheckResultConsumer consumer) {
try {
SomeClass check = someFunction(flag, something);
if (check.IsTrue()) {
consumer.accept(check);
}
} catch(MyException e) {
// handle exception
}
}