模拟python';java中的swith语句

模拟python';java中的swith语句,java,python,connection,Java,Python,Connection,Java中是否有类似Python的和上下文管理器 例如,假设我想做如下事情: getItem(itemID){ Connection c = C.getConnection(); c.open(); try{ Item i = c.query(itemID); }catch(ALLBunchOfErrors){ c.close(); } c.close(); return c; } 在python中,我只有: with( C.ge

Java中是否有类似Python的上下文管理器

例如,假设我想做如下事情:

getItem(itemID){
   Connection c = C.getConnection();
   c.open();
   try{
    Item i = c.query(itemID);
   }catch(ALLBunchOfErrors){
      c.close();
   }

   c.close();
   return c;
}
在python中,我只有:

with( C.getConnection().open() as c):
   Item i = c.query(itemID);
   return i;

现在不行;Java仍然没有为这个模式添加语法糖。尽管如此,它不会像使用(Python)或使用(C#)的那样干净,但您至少可以通过在
finally
块中调用一次
C.close()
来清理一下,而不是像您这样做两次:

try {
    // use c
} finally {
    c.close()
}

这也使它与
with
use
的实际实现方式一致,这是一个
try..finally
块(不是
try..catch

正如扎曼所说,秘密在于最终使用;一般来说:

Resource r = allocateResource();
try {
    // use resource
}
finally {
    r.dispose();
}
注意事项如下:

  • 尝试并最终创建一个变量范围。因此,在try子句中分配资源将不起作用,因为它在finally子句中不可见-您必须在try语句之前声明资源的变量
如果您有多个资源要分配,那么一般的模式适用得很干净,但这对于初学者来说通常并不明显:

Resource1 r1 = allocateResource1();
try {
    // code using r1, but which does not need r2
    Resource r2 = allocateResource2();
    try {
        // code using r1 and r2
    }
    finally {
        r2.dispose();
    }
}
finally {
    r1.dispose();
}
,等等,如果您有更多的资源要分配。如果你有两个,你肯定会尝试避免尝试的深度嵌套。。。最后是声明。不要。您可以获得正确的资源释放和异常处理,而无需嵌套太多尝试。。。最后是语句,但要在不嵌套的情况下使其正确,请尝试。。。最后比深巢还要难看

如果经常需要使用一组资源,可以实现基于函子的方法以避免重复,例如:

interface WithResources {
    public void doStuff(Resource1 r1, Resource2 r2);
}

public static void doWithResources(WithResources withResources) {
    Resource r1 = allocateResource1();
    try {
        Resource r2 = allocateResource2();
        try {
            withResources.doStuff(r1, r2);
        }
        finally {
            r2.dispose();
        }
    }
    finally {
        r1.dispose();
    }
}
您可以这样使用:

doWithResources(new WithResources() {
    public void doStuff(Resource1 r1, Resource2 r2) {
        // code goes here
    }
});
 final _<Item> item = new _<Item>();
 final _<Connection> c = new _<Connection>();
 with( factory, c, new Runnable() {
    public void run(){
        item._ = c._.query( itemId );
    }
});
return item._;
doWithResources将自动正确地处理分配和解除分配,并且您的代码将具有较少的重复(这是一件好事)。然而:

  • Java的匿名类语法过于冗长
  • doStuff中检查的异常使事情变得太复杂了
,我希望在Java7中解决这两点

您可以在Spring中找到此类代码,例如:

  • );做纤维状的东西

有一种替代方法,使用通用包装器,如下所示:

doWithResources(new WithResources() {
    public void doStuff(Resource1 r1, Resource2 r2) {
        // code goes here
    }
});
 final _<Item> item = new _<Item>();
 final _<Connection> c = new _<Connection>();
 with( factory, c, new Runnable() {
    public void run(){
        item._ = c._.query( itemId );
    }
});
return item._;
严格的理论中,您可以重复使用它来执行其他操作,例如删除项目:

    public void deleteItem( final int itemId ) {
        final _<Connection> c = new _<Connection>();
        with( factory, c, new Runnable() {
            public void run(){
               Item item  = c._.query( itemId );
               if( ! item.hasChildren() ) {
                    c._.delete( item );
               }
            }
        });
    }
public void deleteItem(最终int itemId){
最终的c=新的uC();
带(工厂、c、新可运行(){
公开募捐{
Item Item=c.。u2;查询(itemId);
如果(!item.hasChildren()){
c、 十一、删除(项目);
}
}
});
}
或者更新它

    public void update( final int itemId, String newName ) {
        final _<Connection> c = new _<Connection>();
        with( factory, c, new Runnable() {
            public void run(){
               Item item  = c._.query( itemId );
               item.setName( newName );
               c._.update( item );
            }
        });
    }
public void更新(最终int itemId,字符串newName){
最终的c=新的uC();
带(工厂、c、新可运行(){
公开募捐{
Item Item=c.。u2;查询(itemId);
item.setName(新名称);
c、 十一、更新(项目);
}
});
}
无需再次集成try/catch


这里有一个例子证明了这个概念(并且不做任何其他事情)

Java7引入了一个新特性来解决这个问题:“使用资源进行尝试”

语法是将资源放在try关键字后面的括号中:

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
    return br.readLine();
}
在Java7之前,可以使用finally块

BufferedReader br = new BufferedReader(new FileReader(path));
try {
    return br.readLine();
} finally {
    if (br != null) br.close();
}

在Java7中引入了try-with-resources。在此之前,您必须使用try finally块。请参阅此处的文档:

我不太了解使用或Python的
,但如果它类似于使用
的C#
,这最近得到了回答:+1但是:
[const]
[final]
也存在,因此
[with]
也应该有一个标记。我还不能创建它。谢谢。。。我还可以使用模板方法模式,这需要丑陋的类层次结构。干杯。到处都是下划线是什么意思?临时变量名?这不是Java(语言),而是我创建的通用类包装器。你可能会认为它是一个差劲的通过参考的替代品。它的定义是:
class{public E}
:PSorry,我仍然不确定下划线是什么。你是说它们不是java语言的一部分吗?@drozzy:No的意思是
int
for
是。下划线只是另一个类名和另一个字段名。我之所以使用它,是因为它使代码看起来更干净。这里是比较:与常规名称:Using uderscore:diff:Thank相比,函子的东西看起来很有趣。糟糕的是,没有糖可以简化它。而且-你不是说close()而不是dispose()?Java有一个可关闭的接口,“dispose”听起来更一般。这只是伪代码:-p