Cameron McKenzie: Hey, I'm Cameron McKenzie, I'm
the editor in chief over at the server side.com.
And I want to show you a simple example of how to
use try with resources in Java properly. Key to
the try with resources statement is this auto
closable interface right here, as you can see a
whole bunch of interesting classes implemented,
you can see the object stream writer server socket
file, image output stream, anything that should be
closed after it's opened implements this
interface. And it's a super easy interface
implement, it's only got one method called close.
And as long as you've got a class that's
implementing that interface, you can use the try
with resources construct. Now, let me give you an
example of that, I'm going to create a brand new
class here, I'm going to call it try with
resources example. I'm going to put the good old
main method in there, click Finish. And you can
see I got the main method. But before I start, I'm
going to create a class of my own here. Now I'm
going to do a couple of shortcuts here, you
probably don't want to do this in production code,
but I'm going to create a new class in the same
class file called door that's going to implement
that auto closable interface that we just talked
about. Now, as soon as I write this code, it said,
Hey, you got to implement that inherited abstract
method. And I'm like, Well, I can do that just
implement it, don't be problematic. And there we
go, a nice little close method right here. And
this class is now auto closable, we've got the
door, it's got a closed method, why don't I just
do a system dot out dot print line that says, the
door is closed. And all of a sudden, our closed
method has a functional implementation. And now
that's all I do to have to set myself up to use
the try with resource construct, watch this, I'm
going to actually come over here, say, I want to
try to create an instance of that door, I'm going
to trim down that throws exception part there,
because that's going to complicate things. Create
a new instance of this door class, put my try
block after it. This is where I write all of my
code. And now, this code guarantees that when it
runs, this close method will be invoked, I don't
have to do anything more. This may actually bother
some people, I don't even know if I catch your
finally block there. I'll add that in just a
minute. But watch this. If I run this code, even
though I have never invoked the close method
directly. That close method gets called right at
the end of this try block, I'm guaranteed even if
an exception is thrown throw, new runtime
exception. Even if an exception is thrown in this
method, that method close is always going to be
invoked. You can see even with that exception, we
still close the resource. And this is how you can
avoid resource leak. So if you've got a database
connection, if you've got a connection to the file
system, a server socket, make sure that you use
the the automatic Resource Management feature arm
feature of Java, using the try with resources type
of syntax. Now, I'm going to improve this a little
bit, I'm going to have a well I guess a door could
swing. So public void swing, let's swing this
door. System dot print lawn, the door is swinging.
That all saves now in my try block, I'm not going
to throw that exception right away, I'm just going
to say door dot swing, you'll notice that this
door object has scope within that try block. And
of course, you know, I didn't put the catch in
here. But you should always have a catch in there,
right? Catch your exception and do something. And
you know, if you're really clever, you can even
add a finally block.
I couldn't do anything in these blocks. But it's
just nice to see them there. And you can imagine
writing some code. But you'll notice now I'm going
to call this swing method first. And this close
method will be called after it. So if I say run as
a Java application, boom, the door is swinging and
the door is closed. And I never explicitly called
this closed method. And again, even if I throw
that runtime exception and run this, you notice
that closed method always gets called and that's
beautiful. That makes sure that well if somebody
comes in and starts swinging this door when they
leave, well that door is always going to get
closed. Maybe reduce our heating bills. So yes, my
dad Sees McKenzie would love that. Now, there are
some problems that happened when they introduced
this, try with resources construct in Java space
on it there to make it look a little bit more
handsome. One of the problems was the fact that
well, you can run into a situation where two
exceptions get thrown. So imagine I've got a swing
exception and a closed exception, I'm running out
of space on this screen, maybe I should have made
my font smaller. But I've got a swing exception,
I've got a close exception. And let's just imagine
that this swing class throws the swing exception.
And this close method throws the close exception,
I think I called swing a class, but it's just a
method there. So imagine swing throws the swing
exception, the close throws the close exception.
And then when we're actually writing this code.
Inside these methods, these exceptions get thrown.
Now, you shouldn't explicitly throw an exception
like this if you're writing code, because that'll
always happen. But this is just an example to
demonstrate. And, of course, I caught myself there
shouldn't be throw and not throws you throws in
the clause throw when you throw an exception. But
now I have this interesting situation, when this
code runs, the Swing Method is going to throw an
exception. Normally, prior to Java seven, when try
with resources was introduced, you could only have
one exception thrown at a time. But now notice
this close method can throw an exception as well.
When I run this swing method, the Swing Method
throws an exception. We know that even if an
exception is thrown, we know that the close method
is going to run. But here we also get a close
exception. So imagine I said in this cache block.
Hey, give me the class of the exception that has
been caught here. What do you think that would end
up being? Do you think that if I asked for the
class, whether or the class being thrown into that
catch block would be swing? Do you think it would
be close do you think would be both? Do you think
this would run twice? Because we've got two
exceptions being thrown? Well, let's take a look
at what happens here.
Boom, it's actually the swing exception. So what
happens to the close exception? Right? Well, I
mean, both of them are being called when I run
this, I'll run it one more time, boom, you can see
that the close method is being called even though
the Swing Method throws an exception, we only get
a listing of the swing exception here. Where is
that close exception? Well, they introduced a new
concept to deal with this called the suppressed
exception. And so here, if I say system dot out
dot print line, I can say e dot get suppressed.
There's this says here returns an array containing
all the exceptions that were suppressed. So that
close exception is being suppressed. Now I know
that there's one. So I'll say at index zero, by
the way, you should check to make sure that there
are things there are suppressed exceptions in that
list in that array. And then maybe you should loop
through them. But in this example, I know one is
being thrown, it'll be at index zero. And so I'm
explicitly going to try and print it out here. So
I print out the actual exceptions class, and then
I'm going to print out the suppressed exception,
watch what happens here. We end up having the
swing method called, even though it throws an
exception, we close the door, we then get the
swing exception as what you might call the primary
exception. And then after the primary exception is
thrown, we get the close exception afterwards. And
so that gets handled as a suppressed exception.
And so that's how a suppressed exception works.
The idea is, there is this possibility, when
you're using this try with resources construct
that more than one exception will be thrown. The
exception that gets thrown in the try block. The
primary exception is the one that's passed to the
catch. And then any subsequent exceptions that
were thrown during the closing of any resources
get attached as suppressed exceptions, and that's
how try with resources works. And that's why we
have to handle suppressed exceptions. And there
you go. That's how easy it is to use the try with
resources statement in Java. Now if you Enjoy the
tutorial Why don't you subscribe to eye on tech
and head over to the server side dot com we've got
lots of great tutorials on Java Jakarta EE get
DevOps tools and enterprise development in general