Java 7 try-with-resources - what can be in try clause - java

I know that there must be a variable declaration associated with the resource in the try clause.
But as well being assigned a usual resource instantiation, could it instead be assigned an already existing resource eg :
public String getAsString(HttpServletRequest request) throws Exception {
try (BufferedReader in = request.getReader(); ){
etc
}
}
ie. will the BufferedReader be closed automatically just like resources instantiated directly in the try clause ?

Yes. Anything that is AutoCloseable will call the close method. try-with-resource will do that.

We can test whether this is true using this code:
class Main {
public static void main(String[]args) throws Exception {
AutoCloseable _close = getCloseable()
try (AutoCloseable close = _close) {
// ...
}
}
public static AutoCloseable getCloseable() {
return new MyCloseable();
}
}
class MyCloseable implements AutoCloseable {
#Override
public void close() {
System.out.println("Closing");
}
}
The output is "Closing". This means that indeed, AutoCloseables that are created before the try block will still be closed after the try block.
Actually, Java does not care what you put in the () of the try block, as long as it implements AutoCloseable. At runtime, the expression will be automatically evaluated to a value, whether it is a new expression or not.

Yes, BufferedReader will be closed automatically.
Since Java 7, Interface AutoCloseable is added as a SuperInterface of Closeable, so all implementing classes of Closeable (ie. Resource classes) interface automatically inherit AutoCloseable interface.

Related

Java try with resources and `AutoCloseable` interface

I am looking for a Java equivalent for python's with statement, and I read about implementing the AutoCloseable interface and using try with resources.
In python, the context manager (with statement) uses two methods: __enter__ and __exit__, but in Java, the try with resources block uses only close, which is the equivalent of __exit__.
Is there an equivalent for the __enter__ method, in order to perform a certain method automatically when entering the try with resources block, and not only when the block is over?
The equivalent is basically whatever you are calling in the try to get an instance of your AutoCloseable. This could be a constructor like:
try (MyClass obj = new MyClass()) { …
Where the class having such a constructor looks like:
public class MyClass implements AutoCloseable {
public MyClass() {
// do "enter" things...
}
#Override
public void close() {
// close resources
}
}
Depending on what you need "enter" to do, you might instead prefer a static producer for your class, which would look like this:
try (MyClass obj = MyClass.getInstance(someProperties)) { …
Then your class might look something like this:
public class MyClass implements AutoCloseable {
private MyClass() {
// instantiate members
}
public static MyClass getInstance(Properties config) {
// you could implement a singleton pattern or something instead, for example
MyClass obj = new MyClass();
// read properties...
// do "enter" things...
return obj;
}
#Override
public void close() {
// close resources
}
}
You could even call a factory or builder pattern in the try to produce your AutoCloseable. It all depends on your design and what you need the instance to do on "enter".

How does this implementation of AutoClosable work?

I am trying to understand the following code snippet. I understand that AutoClosable interface defines a close() method.
protected AutoCloseable fooAction() {
enableFooResources();
return () -> {
disableFooResources()
};
}
What does the construct of return () -> {} mean? How does it return an AutoClosable object.
Appreciate if someone could point to the name of the language construct so that I can look this up.
The () -> ... syntax is called a lambda expression. They are basically an alternative to anonymous classes that has only one method (though they are not compiled into anonymous classes).
Your code is similar to:
protected AutoCloseable fooAction() {
enableFooResources();
return new AutoCloseable() {
#Override
public void close() throws Exception {
SurroundingClass.this.disableResources();
}
}
}
The intention is likely to provide a way for the caller to close whatever resource fooAction is going to do.
Learn more about lambdas here.

Try-with-resources when calling super constructor

Is there any good way of using try-with-resources when opening an InputStream in a constructor and then passing that to a super constructor?
Basically what I want to do is this:
public class A {
public A(InputStream stream) {
// Do something with the stream but don't close it since we didn't open it
}
}
public class B {
public B(File file) {
// We open the stream so we need to ensure it's properly closed
try (FileInputStream stream = new FileInputStream(file)) {
super(new FileInputStream(file));
}
}
}
But, of course, since super must be the first statement in the constructor this isn't allowed. Is there any good way of achieving this?
Consider using a static factory method instead of using the constructor directly. Make at least B's constructor private, and create a method such as
private B(InputStream is) {
super(is);
// Whatever else is needed
}
public static B newInstance(File file) {
B result;
try (FileInputStream stream = new FileInputStream(file)) {
result = new B(stream);
}
// Further processing
return result;
}
Another way to go :
public class A {
protected A(){
// so he can't be called from the outside, subclass ensure that init is done properly.
}
public A(InputStream stream) {
init(stream);
}
// not be able to call it from outside
protected final init(InputStream is){
//here goes the code
}
}
public class B {
public B(File file) {
// We open the stream so we need to ensure it's properly closed
try (FileInputStream stream = new FileInputStream(file)) {
init(stream);
}
}
}
I'm posting this here as a possible answer, however here i'm consdering :
You can update A's code
You're moving constructor's code to an init method, thanks to protected empty arg constructor, only subclasses have to handle the call to init properly. Some may see that as not so well designed. My point is as soon your subclassing something, you have to know more about it that just when you just using it.
Sadly I do not have a compiler on hand to test on but could you not do as follows.
public class B {
private static InputStream file2stream(File f){
// We open the stream so we need to ensure it's properly closed
try (FileInputStream stream = new FileInputStream(file)) {
return stream;
}catch(/*what you need to catch*/){
//cleanup
// possibly throw runtime exception
}
}
public B(File file) {
super(file2stream(file))
}
}

How to handle Exception from Singleton java?

I have a singleton class
public class SingletonText {
private static final CompositeText text = new CompositeText(new TextReader("text/text.txt").readFile());
public SingletonText() {}
public static CompositeText getInstance() {
return text;
}}
And TextReader constructor that could throw FileNameEception
public TextReader(String filename) throws FileNameException{
if(!filename.matches("[A-Za-z0-9]*\\.txt"))
throw new FileNameException("Wrong file name!");
file = new File(filename);
}
How can I rethrow it to main and catch it there?
Main class
public class TextRunner {
public static void main(String[] args) {
// write your code here
SingletonText.getInstance().parse();
System.out.println("Parsed text:\n");
SingletonText.getInstance().print();
System.out.println("\n\n(Var8)Task1:");
SortWords.sortWords(SingletonText.getInstance().getText().toString(), "^[AEIOUaeiou].*", new FirstLetterComparator());
System.out.println("\n\n(Var9)Task2:");
SortWords.sortWords(SingletonText.getInstance().getText().toString(), "^[A-Za-z].*", new LetterColComparator());
System.out.println("\n\n(Var16)Task3:");
String result = SubStringReplace.replace(SingletonText.getInstance()
.searchSentence(".*IfElseDemo.*"), 3, "EPAM");
System.out.println(result);
}}
Static block is executed only when class is loaded for the first time, so you can have something as below which will allow you to re-throw the exception. In you main method, you will surround getInstance() invocation in a try-catch block and then in catch you can do whatever you are looking for.
In case of exception, this exception will be thrown and re-thrown (from you static block) only once, at time of class loading. What #Alexander Pogrebnyak has said is also true.
Looking at the code you have provided, since you are always reading text/text.txt files so below approach will work. In case you are looking to read different files and then re-throwing exception then that becomes all together a different story, and you hadn't asked that part neither the code you have provided shows the same. In any case, if that's what you are looking for then:
you need to create a singleton object of your CompositeText class.
create a setter method will create an object TextReader class using the file name string passed.
that setter method will have the try-catch block, and in the catch block you will re-throw the exception so that you can catch again in main method.
P.S.: since static blocks are executed only once when class is loaded and class is loaded only once per JVM (until you have custom class loaders and overriding the behavior) so this ensures that this singleton is thread-safe.
Code:
public class SingletonText {
private static CompositeText text = null;
static{
try {
text = new CompositeText(new TextReader("text/text.txt").readFile());
} catch (FileNameException e) {
// TODO: re-throw whatever you want
}
}
public SingletonText() {}
public static CompositeText getInstance() {
return text;
}
}
try to lazy initialze the singleton.
something like this:
public class SingletonText {
private static CompositeText text;
public SingletonText() {
}
public static CompositeText getInstance() {
if (text ==null) {
text = new CompositeText(new TextReader("text/text.txt").readFile());
}
return text;
}
}
Also, you need to declare the constructor private, and if it multi-threaded application you need to synchronized the new statement with double check locking. see this in wiki:
https://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java
Enjoy..
You will get java.lang.ExceptionInInitializerError when your singleton static initializer will fail.
As a cause it will have your FileNameException.
If you don't do anything, default exception handler will print the whole stack trace to standard error.

Call implemented interface overriden method from a class

I'm starting to do a bit of advanced things in Java (For me are advanced xD).
I had this:
interface ResultSet {
public void close();
}
class DbResult {
ResultSet data;
Statement statement;
public void close() {
this.data.close();
this.statement.close();
}
}
I've tried to do this:
interface ResultSet { //I think that is abstract or something
public void close();
}
abstract class DbResult implements ResultSet {
Statement statement;
#Override
public void close() {
super.close();
this.statement.close();
}
}
Obviously it don't works because ResultSet is not a superclass. I also tried to make DbResult an interface and extending ResultSet but it tells me that interface methods cannot have a body, so I don't know how to do this.
I'm trying to do this so I can close the result statement and result having only one variable instead of 2, so is less prone to memory leaks for forgetting closing the statement.
The Database class queries the database this way:
class Database {
private Connection connection;
/* Here a constructor that
inits the connection and such things */
public DbResult query(String q) {
Statement statement = this.connection.createStatement();
DbResult result = (DbResult)statement.executeQuery(q);
result.statement = statement;
return result;
}
EDIT:
Ok, now that I know that I can't I want to know if I can do this in a hackish form I though:
Is there a way of checking if a method that does not exists is called in a class, catch it and invoke that method name in another variable?
For example, ResultSet has a method called getString(). I want to know if is possible to call DbResult.getString("blah"); and DbResult will redirect that method to this.data but withou implementing the getString method inside the DbResult class.
I would like to know if is possible because there are tons of functions in the ResultSet and calling DbResult.data.METHOD is less elegant than DbResult.METHOD.
Is there a way of checking if a method that does not exists is called
in a class, catch it and invoke that method name in another variable?
So you want to wrap calls to an instance without having to extend it or implementing each of its methods, that's actually possible, but only for methods exposed over interfaces.
Good news is that ResultSet is in fact an interface.
This can be done by means of dynamic proxies (see Proxy and InvocationHandler).
You can create a Proxy backed by an InvocationHandler which wraps the ResultSet. Any calls to your proxy instance will be delegated to the InvocationHandler, which can process them directly or, in your case, delegate them to the wrapped actual ResultSet instance.
public class MyResultSetInvocationHandler implements InvocationHandler {
private final ResultSet wrappedResultSet;
private MyResultSetInvocationHandler(ResultSet resultSet) {
wrappedResultSet = resultSet;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
// call method on delegate
Object result = method.invoke(wrappedResultSet, args);
// optionally do something with the result, and return it afterwards
return result;
}
catch (Throwable ex) {
// handle exception, or rethrow it
throw ex;
}
}
/**
* Factory method, creates a dynamic proxy wrapping the given result set.
*/
public static ResultSet wrap(ResultSet delegate) {
MyResultSetInvocationHandler handler = new MyResultSetInvocationHandler(delegate);
return (ResultSet) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[] { ResultSet.class }, handler);
}
}
Usage:
// the actual result set
ResultSet resultSet = ...
// and your wrapped proxy/handler as a surrogate
resultSet = MyResultSetInvocationHandler.wrap(resultSet);
Perhaps what you want to use is an abstract class and not an interface, something like:
interface A2 {
void foo();
void otherAbstractMethod();
}
abstract class AbstractA2 implements A2 {
#Override // implemented metthod
public void foo() {
System.out.println("From the default method");
}
#Override //unimplemented abstract method
public abstract void otherAbstractMethod();
}
class B2 extends AbstractA2 {
#Override
public void foo() {
super.foo();
System.out.println("From the override");
}
#Override
public void otherAbstractMethod() {
// TODO add some code
// the line below won't compile
// super.otherAbstractMethod();
}
}
and to test it
public class TestA {
public static void main(String[] args) {
A2 myA = new B2();
myA.foo();
}
}
Edit
Regarding the changes in your question, which changes everything and drastically, I'm confused (again). Is ResultSet your interface, or are you trying to implement the java.sql.ResultSet? If the latter, your code will be fraught with difficulty since your class cannot extend and cannot substitute for the actual type of ResultSet returned by the query. I don't see any substitute for your using composition and not inheritance. In other words, go with what you were originally doing -- creating classes that contain ResultSet fields but not one that implements the interface.
Note that you can implement ResultSet if you use the Decorator Pattern. With this you would create your own class that is a "wrapper" for the original type, and it will require you to use composition and inheritance, and to create all the needed methods for the interface and then delegate them to the ResultSet component.
For example, ResultSet has a method called getString(). I want to know if is possible to call DbResult.getString("blah"); and DbResult will redirect that method to this.data but withou implementing the getString method inside the DbResult class.
No, you would have to have all these methods implemented in your child decorator class.
Guess what: it's already part of Java (since version 7):
Java API Documentation: java.lang.AutoCloseable
public interface AutoCloseable {
void close();
}
ResultSet, Statement (and many other classes) already implement this interface.
And the best thing: resources managed by the try in a try-statement are automatically closed, if they implement this interface.

Categories

Resources