使用java匿名函数返回值
从C#转换到Java,并试图清除一些代码中的大量连接泄漏 为了防止泄漏,我会做如下的事情使用java匿名函数返回值,java,lambda,Java,Lambda,从C#转换到Java,并试图清除一些代码中的大量连接泄漏 为了防止泄漏,我会做如下的事情 public class DB{ public interface StatementUser{ public void useit(Statement cmd); } public static void UseCommand(StatementUser usingfunc){ try(Connection cnn = new Connectio
public class DB{
public interface StatementUser{
public void useit(Statement cmd);
}
public static void UseCommand(StatementUser usingfunc){
try(Connection cnn = new Connection(...)){
cnn.open();
try(Statement stmt = new Statement(cnn)){
usingfunc(stmt);
}
}
}
static void main(string[] args){
int affected = 0;
DB.useStatement((stmt) -> {
// THIS STATEMENT IS DISALLOWED
affected = ... select/update... whatever
});
System.out.println("Records: " + affected);
}
}
我喜欢这个委托,因为它处理清理工作,但仍然将与数据的大部分交互留给了开发人员的创造力
我发现对受影响的的赋值被认为是访问其范围之外的变量,并且是不允许的。所以现在我有点不知所措,不知道如何在Java中执行类似的操作(我想保持connection/statement对象的通用用法)
我想到的每一件事都让事情变得更加丑陋,所以我怀疑我只是在走一条完全没有出路的道路
Java做这种事情的方式是什么?(我知道这可能与我预期的大不相同)编写此代码的另一种方法如下:
package controllers;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class DB {
public interface StatementUser<T> {
T run(Statement cmd);
}
public static <T> T runStatement(StatementUser<T> usingfunc) {
try(Connection cnn = getConnection()){
try(Statement stmt = cnn.createStatement()){
return usingfunc.run(stmt);
}
} catch(SQLException ex) {
throw new RuntimeException(ex);
}
}
private static Connection getConnection() throws SQLException {
return ...; // someway to acquire a connection
}
public static void main(String[] args) {
int affected = DB.runStatement(cmd -> {
// do something with the statement
return 10;
});
System.out.println(affected);
}
}
包控制器;
导入java.sql.Connection;
导入java.sql.SQLException;
导入java.sql.Statement;
公共类数据库{
公共接口语句用户{
T运行(语句cmd);
}
公共静态runt语句(StatementUser usingfunc){
尝试(连接cnn=getConnection()){
try(语句stmt=cnn.createStatement()){
使用函数运行返回(stmt);
}
}catch(SQLException-ex){
抛出新的运行时异常(ex);
}
}
私有静态连接getConnection()引发SQLException{
return…;//以某种方式获取连接
}
公共静态void main(字符串[]args){
int impact=DB.runStatement(cmd->{
//对这个声明做点什么
返回10;
});
系统输出打印项次(受影响);
}
}
编写此代码的另一种方法如下:
package controllers;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class DB {
public interface StatementUser<T> {
T run(Statement cmd);
}
public static <T> T runStatement(StatementUser<T> usingfunc) {
try(Connection cnn = getConnection()){
try(Statement stmt = cnn.createStatement()){
return usingfunc.run(stmt);
}
} catch(SQLException ex) {
throw new RuntimeException(ex);
}
}
private static Connection getConnection() throws SQLException {
return ...; // someway to acquire a connection
}
public static void main(String[] args) {
int affected = DB.runStatement(cmd -> {
// do something with the statement
return 10;
});
System.out.println(affected);
}
}
包控制器;
导入java.sql.Connection;
导入java.sql.SQLException;
导入java.sql.Statement;
公共类数据库{
公共接口语句用户{
T运行(语句cmd);
}
公共静态runt语句(StatementUser usingfunc){
尝试(连接cnn=getConnection()){
try(语句stmt=cnn.createStatement()){
使用函数运行返回(stmt);
}
}catch(SQLException-ex){
抛出新的运行时异常(ex);
}
}
私有静态连接getConnection()引发SQLException{
return…;//以某种方式获取连接
}
公共静态void main(字符串[]args){
int impact=DB.runStatement(cmd->{
//对这个声明做点什么
返回10;
});
系统输出打印项次(受影响);
}
}
不允许的变量访问的确切位置在哪里?这种方法看起来不错。如果您的意思是分配给受影响的
,可能应该是lambda的返回值(与您现在的无效
相反)。否则,您可以使用一个可更新的容器类(比如这里的AtomicInteger)。我开始想象在整个代码中有一堆快速类被忽略。我不知道一个预先存在的AtomicInteger
,它也提供了一个很好的接口。@我越想它,就越喜欢它。如果要显示重写后使用AtomicInteger
作为答案的main方法,我可以对其进行投票。嗯。。我非常喜欢有返回值的版本。更“功能性”。不允许的变量访问究竟在哪里?这种方法看起来不错。如果您的意思是分配给受影响的
,可能应该是lambda的返回值(与您现在的无效
相反)。否则,您可以使用一个可更新的容器类(比如这里的AtomicInteger)。我开始想象在整个代码中有一堆快速类被忽略。我不知道一个预先存在的AtomicInteger
,它也提供了一个很好的接口。@我越想它,就越喜欢它。如果要显示重写后使用AtomicInteger
作为答案的main方法,我可以对其进行投票。嗯。。我非常喜欢有返回值的版本。更具“功能性”。当我看到这一点时,我手握着我的前额:有些事情很明显(事后看来)。谢谢顺便说一下,我喜欢“<代码> SqLExcExabor <代码>的包装,这是一个很好的触感。对于将来的读者来说,考虑把它改为<代码> RunNo连接< /Cord>,对控制语句的创建可能有(或者可能没有)好处。我不理解RunScript的定义中的<代码> T < /代码>语法。你能解释一下吗?当我看到这一幕时,我用手捂着额头:有些事情很明显(事后看来)。谢谢顺便说一下,我喜欢“<代码> SqLExcExabor <代码>的包装,这是一个很好的触感。对于将来的读者来说,考虑把它改为<代码> RunNo连接< /Cord>,对控制语句的创建可能有(或者可能没有)好处。我不理解RunScript的定义中的<代码> T < /代码>语法。你能解释一下吗?