Python imitation Using instruction in java

Is there something like Python with a context manager in Java?

For example, I want to do something like the following:

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

where in python i just:

 with( C.getConnection().open() as c): Item i = c.query(itemID); return i; 
+6
java python connection
source share
5 answers

Not now; Java still does not add syntactic sugar for this template. However, it will not be as clean as with (Python) or using (C #), but you can at least clean it up a bit by simply having one call to c.close() inside the finally block, and not twice as you did it:

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

This also brings it into line with how both with and using are actually executed, which is a try..finally block (not a try..catch ).

+5
source share

Java 7 introduced a new feature to solve this problem: "try with resources"

http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

Quit a resource silently using try-with-resources

The syntax is a bit strange, but workable (and, of course, better than before).

+14
source share

As Tsaman said, the secret is finally used; usually,

 Resource r = allocateResource(); try { // use resource } finally { r.dispose(); } 

What should be noted here:

  • try and finally create a variable region. Therefore, highlighting your resource in the try clause will not work, because it will not be visible in the finally clause - you need to declare the resource variable before the try statement.

If you have several resources to allocate, the general template is applied cleanly, but this is often not obvious to beginners:

 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(); } 

etc. etc. if you have more resources to allocate. If you have a couple of them, you will probably be tempted to try to avoid the deep nesting of attempts ... finally. Not. You can get the right to free resources and handle exceptions without investing so many attempts ... finally asserting, but getting this right without trying to nest ... finally even more ugly than deep nesting.

If you often need to use a set of resources, you can implement a functor-based method to avoid repetition, for example:

 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(); } } 

What you can use as follows:

 doWithResources(new WithResources() { public void doStuff(Resource1 r1, Resource2 r2) { // code goes here } }); 

doWithResources automatically handles the allocation and release correctly, and your code will have fewer repetitions (which is good). But:

  • Java syntax for anonymous classes is overly verbose
  • Checked exceptions in doStuff complicate things too much.

two points that I hope will be resolved in Java 7.

This code can be found in Spring, for example:

+3
source share

try-with-resources was introduced in Java 7. Before that, you had to use try-finally blocks. See the documentation here: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

+2
source share

There is an alternative using a common shell, such as:

  final _<Item> item = new _<Item>(); final _<Connection> c = new _<Connection>(); with( factory, c, new Runnable() { public void run(){ item._ = c._.query( itemId ); } }); return item._; 

NOTE. The Java method is the one you just described. This is different for fun and experimentation:

_ is a common shell, and the with function is a utility class defined elsewhere as:

 class WithUtil { public static void with( ConnectionFactory factory, _<Connection> c, Runnable block ) { try { c._ = factory.getConnection(); c._.open(); block.run(); } catch( Exception ioe ){ }finally{ if( c._ != null ) try { c._.close(); } catch( IOException ioe ){} } } } 

In a rigorous theory, you can reuse it to perform other actions, such as deleting an element:

  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 ); } } }); } 

or update it

  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 ); } }); } 

Without re-integration of try / catch.

Here's a full working demo that confirms the concept (and does nothing)

+1
source share

All Articles