在支持 java.lang.Exception 且没有 in/out 参数的相同包装上下文中执行通用代码块的好方法?
Nice way of executing generic code blocks in same wrapping context supporting java.lang.Exception with no in/out params?
我一直在寻找这样的解决方案:
(更详细地说:对于某些 Maven 插件 运行 几个不同的构建代码 phases/goals):
void foo() {
execCode( () -> doBar() ) ;
execCode( () -> new File("/baz.txt").create() ) ;
execCode( () -> {
System.out.println( "test" ) ;
throw new MojoFailureException("problem 1") ;
}) ;
}
void execCode( Code code ) throws MojoFailureException {
try {
// ... some common initialization / param parsing here ...
code.run() ;
} catch( Exception e ) {
// ... common exception handling throwing e.g. MojoFailureException ...
}
}
支持(主要是下面的(E)、(G)和(S) ):
- (E):代码块抛出任何
java.lang.Exception
- (V):不需要进出 values/objects
- (S):简短,易于 read/write 代码(最小的混乱)
- 同时避免 IDE 警告并处理它(例如通过
@Ignore
处理未使用的通用类型参数)
- (8): Java 8+支持
- (L):没有进一步的 lib/jar 依赖项,如果可能(非常常见的 Google Guava 或 Apache Commons 也可以)
- (G): 通用上下文(例如一些构建任务),只需要知道完成某些事情 should/will 就可以了,但是正确的异常处理和其他东西(每个调用共有的)应该被封装
简而言之找到的最佳策略:
import java.util.concurrent.Callable;
// ...
void foo() {
execCode( () -> doBar() ) ;
execCode( () -> 5 + 2 ) ;
execCode( () -> { System.out.println( "test" ) ; return 0 ; }) ;
}
void execCode( Callable<Object> code ) {
try {
code.call() ;
} catch( Exception e ) {
// ...
}
}
更多详情:
解决方案 部分在其他答案中找到及其缺点 以上:
- (S.L):使用
java.util.concurrent.Callable
(上述解决方案)
- 满足以上所有要求
如果需要,- 也可以很好地处理一些 return 值
- (S.F):使用
java.util.Function
- 不支持(E)
- 尤其是 (V) 更混乱 ((S)) 并且语义混乱
- 例如
void foo() { execCode( (i) -> doBar() ) ... void execCode( Function< Void, Void > code ) { ... code.apply( null ) ... }
- 另见 this answer
- (S.I): 创建一些 自定义
interface
(class) 来完成它
- 与(S)
矛盾
- 例如
interface Code { abstract void run() throws Exception; }
- 另见 this answer
- (S.M):使用像
this::doBar
这样的方法引用
- 特殊情况,如果代码(已经)在某些对象方法中有助于 (S)
,则可能非常简短和优雅
- 将与
execCode( Callable<Object> ... ) { ... }
一起工作
- 但没有
execCode( Runnable ... ) { ... }
- 与 (E)
相矛盾
- 另见 this answer
- (S.R):使用
java.lang.Runnable
- 与 (E) 相矛盾,因此 (S) 因为它只允许抛出
RuntimeException
但不允许检查
- 另见 this answer
- (S.A):使用
java.lang.AutoCloseable
- 它符合 (E)、(V) 和 (L) 要求,但它至少需要一些注释来解释,为什么有一个
execCode( AutoCloseable code ) { ... code.close() ; ... }
尽管代码不必对语义关闭上下文做任何事情:)
- (S.C):使用
java.util.function.Consumer
- 不支持(E)
- 另见 this answer* (S.X):使用
java.lang.reflect.Method
- 会特别矛盾(S)
- 另见 this answer
- (S.7): 命令模式解决方法
- 如果它必须 Java 7- 兼容(与 (8) 相矛盾)this answer 与命令模式可能是一些好的解决方案
我一直在寻找这样的解决方案:
(更详细地说:对于某些 Maven 插件 运行 几个不同的构建代码 phases/goals):
void foo() {
execCode( () -> doBar() ) ;
execCode( () -> new File("/baz.txt").create() ) ;
execCode( () -> {
System.out.println( "test" ) ;
throw new MojoFailureException("problem 1") ;
}) ;
}
void execCode( Code code ) throws MojoFailureException {
try {
// ... some common initialization / param parsing here ...
code.run() ;
} catch( Exception e ) {
// ... common exception handling throwing e.g. MojoFailureException ...
}
}
支持(主要是下面的(E)、(G)和(S) ):
- (E):代码块抛出任何
java.lang.Exception
- (V):不需要进出 values/objects
- (S):简短,易于 read/write 代码(最小的混乱)
- 同时避免 IDE 警告并处理它(例如通过
@Ignore
处理未使用的通用类型参数)
- 同时避免 IDE 警告并处理它(例如通过
- (8): Java 8+支持
- (L):没有进一步的 lib/jar 依赖项,如果可能(非常常见的 Google Guava 或 Apache Commons 也可以)
- (G): 通用上下文(例如一些构建任务),只需要知道完成某些事情 should/will 就可以了,但是正确的异常处理和其他东西(每个调用共有的)应该被封装
简而言之找到的最佳策略:
import java.util.concurrent.Callable;
// ...
void foo() {
execCode( () -> doBar() ) ;
execCode( () -> 5 + 2 ) ;
execCode( () -> { System.out.println( "test" ) ; return 0 ; }) ;
}
void execCode( Callable<Object> code ) {
try {
code.call() ;
} catch( Exception e ) {
// ...
}
}
更多详情:
解决方案 部分在其他答案中找到及其缺点 以上:
- (S.L):使用
java.util.concurrent.Callable
(上述解决方案)- 满足以上所有要求 如果需要,
- 也可以很好地处理一些 return 值
- (S.F):使用
java.util.Function
- 不支持(E)
- 尤其是 (V) 更混乱 ((S)) 并且语义混乱
- 例如
void foo() { execCode( (i) -> doBar() ) ... void execCode( Function< Void, Void > code ) { ... code.apply( null ) ... }
- 另见 this answer
- (S.I): 创建一些 自定义
interface
(class) 来完成它- 与(S) 矛盾
- 例如
interface Code { abstract void run() throws Exception; }
- 另见 this answer
- (S.M):使用像
this::doBar
这样的方法引用- 特殊情况,如果代码(已经)在某些对象方法中有助于 (S) ,则可能非常简短和优雅
- 将与
execCode( Callable<Object> ... ) { ... }
一起工作
- 但没有
execCode( Runnable ... ) { ... }
- 与 (E) 相矛盾
- 另见 this answer
- (S.R):使用
java.lang.Runnable
- 与 (E) 相矛盾,因此 (S) 因为它只允许抛出
RuntimeException
但不允许检查 - 另见 this answer
- 与 (E) 相矛盾,因此 (S) 因为它只允许抛出
- (S.A):使用
java.lang.AutoCloseable
- 它符合 (E)、(V) 和 (L) 要求,但它至少需要一些注释来解释,为什么有一个
execCode( AutoCloseable code ) { ... code.close() ; ... }
尽管代码不必对语义关闭上下文做任何事情:)
- 它符合 (E)、(V) 和 (L) 要求,但它至少需要一些注释来解释,为什么有一个
- (S.C):使用
java.util.function.Consumer
- 不支持(E)
- 另见 this answer* (S.X):使用
java.lang.reflect.Method
- 会特别矛盾(S)
- 另见 this answer
- (S.7): 命令模式解决方法
- 如果它必须 Java 7- 兼容(与 (8) 相矛盾)this answer 与命令模式可能是一些好的解决方案