Approaches for simplifying try / catch in Java - java

I'm looking for ways to simplify lots of ugly try catch code all over the place. For instance I'm seeing:
try {
objectA.setFieldX(objectB.getFieldY());
}
catch(NullPointerException e) {
...stuff
}
catch(OtherException e) {
...stuff
}
This kind of thing is repeated all over the place for the various fields, some are slightly different in behavior based on if the field is optional or not.
It is bulky, poorly documented, and leaves the reader with the distinct impression that (aside from being poor code) it might be wrong.
If my DataTransferObejcts had (in addition to the standard set(value) and get()) "generic" get and set methods that took some kind of enumerated FieldID (like get(), or set(, object value)- then (in the class with many sets, wrapped in ugly try/catches) I could simply define some helpers like:
setRequiredField(objSource, <FieldIDsource>, objDest, <FieldIDdest) {
object SourceField = objSource.get(<FieldIDsource>);
if (sourceField != null) {
try {
objDest.set(<FieldIDdest>, SourceField);
}
catch (OtherException) {
... stuff (like logging) here
}
}
else {
... stuff (like logging) here
}
}
Then the method doing all the sets would have code like:
setRequiredField(source, <FieldIDAsource>, dest, <FieldIDAdest>);
setOptionalField(source, <FieldIDBsource>, dest, <FieldIDBdest>);
It becomes a lot less bulky, more readable, more correct....
...but there are some issues like:
1) casting up the wazoo: In the generic methods (in the Data Transfer Objects) I'd need to do a lot of casting.
2) making the generic methods complete/correct: I suppose using an Enum I could lock things up somewhat but there is a worry of making some mistake in the generic methods (makes me want to "generate" the Data Transfer Objects with something like FreeMarker- but they have some "domain logic" in them...).
Anyway, if someone has some pointers how to do this right I'd like to know

Actually, this is a clear example of something that can be solved via Aspect Oriented Programming (AOP). The idea is you can inject standard logic for issues that cut across your whole application. Classic examples are error handling and logging. There are several ways to do AOP with Java including Spring and AspectJ. See http://www.voelter.de/data/articles/aop/aop.html for more information.

You should refer the following thread in stack overflow
When to choose checked and unchecked exceptions
The main idea is to only catch exception with which you can do something more. Otherwise you should let the exception propagate to the last layer and only catch Exception there directly before logging it.

If I understand your problem you are trying to copy properties from one bean to another. You may consider using dozer for that...

Related

Return optional value, depending on exception thrown by method used inside stream

Im trying to implement validation module used for handling events. The validation module is based on simple interface:
public interface Validator {
Optional<ValidationException> validate(Event event);
}
Existing code base in my team relies on the wrapping exception mechanism - I cannot really play with it.
I have encountered problems when implementing new validator, that is responsible for validating single event, in two terms.
Assume the event is PlayWithDogEvent, and it contains Toys a dog can play with.
Flow of validation of such event:
For each toy,
Check if its a ball
If its a ball, it should be not too large.
If any of the toys is either not a ball/too big ball, my validate(Event event) method should return Optional.of(new ValidationException("some msg")).
I have implemented my validator the following way:
public class ValidBallsOnlyValidator implements Validator {
#Override
public Optional<ValidationException> validate(Event event) {
try {
event.getToys().forEach(this::validateSingleToy);
return Optional.empty();
} catch (InvalidToyException ex) {
return Optional.of(new ValidationException(ex.getMessage()));
}
}
private void validateSingleToy(Toy toy) {
// In real code the optional here is kinda mandatory
Optional<Toy> potentialBall = castToyToBall(toy);
// Im using Java 8
if(potentiallBall.isPresent()) {
checkIfBallIsOfValidSize(potentialBall.get(), "exampleSize");
} else {
throw new InvalidToyException("The toy is not a ball!")
}
}
private void checkIfBallIsOfValidSize(Toy toy, String size) {
if(toyTooLarge(toy, size)) throw new InvalidToyException("The ball is too big!")
}
}
The piece seems to work just fine, but im uncomfortable with the way it looks. My biggest concern is whether it is a good practice to place whole stream processing inside single try. Moreover, I don't think such mixing of exception-catching + returning optionals is elegant.
I could use some advice and/or best practices for such scenarios.
but im uncomfortable with the way it looks.
The API you're working against is crazy design. The approach to dealing with silly APIs is generally the same:
Try to fix it 'upstream': Make a pull request, talk to the team that made it, etc.
If and only if that option has been exhausted, then [A] write whatever ugly hackery you have to, to make it work, [B] restrict the ugliness to as small a snippet of code as you can; this may involve writing a wrapper that 'contains' the ugly, and finally [C] do not worry about code elegance within the restricted 'ugly is okay here' area.
The reason the API is bizarre is that it is both getting validation wrong, and not capitalizing on the benefits of their mistake (as in, if I'm wrong about their approach being wrong, then at least they aren't doing the best job at their approach).
Specifically, an exception is a return value, in the sense that it is a way to return from a method. Why isn't that interface:
public interface Validator {
void validate(Event event) throws ValidationException;
}
More generally, validation is not a 'there is at most one thing wrong' situation, and that goes towards your problem with 'it feels weird to write a try/catch around the whole thing'.
Multiple things can be wrong. There could be 5 toys, one of which is a ball but too large, and one of which is a squeaky toy. It is weird to report only one error (and presumably, an arbitrarily chosen one).
If you're going to go with the route of not throwing validation exceptions but returning validation issues, then the issues should presumably not be exceptions in the first place, but some other object, and, you should be working with a List<ValidationIssue> and not with an Optional<ValidationIssue>. You've gotten rid of an optional, which is always a win, and you now can handle multiple issues in one go. If the 'end point' that processes all this is fundamentally incapable of dealing with more than one problem at the time, that's okay: They can just treat that list as an effective optional, with list.isEmpty() serving as the 'all is well' indicator, and list.get(0) otherwise used to get the first problem (that being the only problem this one-error-at-a-time system can deal with).
This goes to code elegance, the only meaningful way to define that word 'elegance': It's code that is easier to test, easier to understand, and more flexible. It's more flexible: If later on the endpoint code that deals with validation errors is updated to be capable of dealing with more than one, you can now do that without touching the code that makes validation issue objects.
Thus, rewrite it all. Either:
Make the API design such that the point is to THROW that exception, not to shove it into an optional, -or-
Make the API list-based, also get rid of optional (yay!) and probably don't work with a validation issue object that extends SomeException. If you're not gonna throw it, don't make it a throwable.
If that's not okay, mostly just don't worry about elegance so much - elegance is off the table once you're forced to work with badly designed APIs.
However, there's of course almost always some style notes to provide for any code.
return Optional.of(new ValidationException(ex.getMessage()));
Ordinarily, this is extremely bad exception handling and your linter tool SHOULD be flagging this down as unacceptable. If wrapping exceptions, you want the cause to remain to preserve both the stack trace and any exception-type-specific information. You're getting rid of all that by ignoring everything about ex, except for its message. Ordinarily, this should be new ValidationException("Some string that adds appropriate context", ex) - thus preserving the chain. If there is no context to add / it is hard to imagine what this might be, then you shouldn't be wrapping at all, and instead throwing the original exception onwards.
However, given that exceptions are being abused here, perhaps this code is okay - this again goes to the central point: Once you're committed to working with a badly designed API, rules of thumb on proper code style go right out the window.
private void checkIfBallIsOfValidSize(Toy toy, String size) {
if(toyTooLarge(toy, size)) throw new InvalidToyException("The ball is too big!")
}
Yes, this is a good idea - whilst the API expects you not to throw exceptions but to wrap them in optionals, that part is bad, and you should usually not perpetuate a mistake even if that means your code starts differing in style.
event.getToys().forEach(this::validateSingleToy);
Generally speaking, using the forEach method directly, or .stream().forEach(), is a code smell. forEach should be used in only two cases:
It's the terminal on a bunch of stream ops (.stream().filter().flatMap().map()....forEach - that'd be fine).
You already have a Consumer<T> object and want it to run for each element in a list.
You have neither. This code is best written as:
for (var toy : event.getToys()) validateSingleToy(toy);
Lambdas have 3 downsides (which turn into upsides if using lambdas as they were fully intended, namely as code that may run in some different context):
Not control flow transparent.
Not mutable local var transparent.
Not checked exception type transparent.
3 things you lose, and you gain nothing in return. When there are 2 equally succint and clear ways to do the same thing, but one of the two is applicable in a strict superset of scenarios, always write it in the superset style, because code consistency is a worthwhile goal, and that leads to more consistency (it's worthwhile in that it reduces style friction and lowers learning curves).
That rule applies here.
Returning exceptions instead of returning them is weird, but whatever. (Why not return a ValidationResult object instead? Exceptions are usually intended to be thrown and caught).
But you could change your private methods to also return Optional instances which would make it easier to combine them. It would also avoid mixing throwing and returning and streams. Not sure if that is what you are looking for?
public class ValidBallsOnlyValidator implements Validator {
#Override
public Optional<ValidationException> validate(Event event)
return event.getToys()
.stream()
.filter(Optional::isPresent)
.findFirst()
.map(ex -> new ValidationException(ex.getMessage()));
}
private Optional<InvalidToyException> validateSingleToy(Toy toy) {
// In real code the optional here is kinda mandatory
Optional<Toy> potentialBall = castToyToBall(toy);
if(potentiallBall.isPresent()) {
return checkIfBallIsOfValidSize(potentialBall.get(), "exampleSize");
} else {
return Optional.of(new InvalidToyException("The toy is not a ball!"));
}
}
private Optional<InvalidToyException> checkIfBallIsOfValidSize(Toy toy, String size) {
if(toyTooLarge(toy, size)) return Optional.of(new InvalidToyException("The ball is too big!"));
return Optional.empty();
}
}

How to cast an exception via Java annotation?

Too often one sees the following pattern in enterprising Java programs
public Something myMethod() throws MyException {
try {
// may throw checked DbException:
Connection c = openDataBase("connectionstring");
// ... other code throwing more checked exceptions ...
} catch(DbException e) {
throw new MyException(e);
}
return something;
}
...or any other mechanism to "cast" one checked exception type that is not declared in the method header to the one that is. Very often this "try-catch-cast"-block must go into every method of such a class.
I wonder, how to implement an annotation, that catches and converts exceptions?
The using code should then look like this:
#ConvertException(MyException, DbException)
public Something myMethod() throws MyException {
// may throw checked DbException:
Connection c = openDataBase("connectionstring");
// ...
return something;
}
Of course, Maybe one has to write MyException.class or "MyException" instead. It should also be possible to chain these annotations, or list multiple exceptions to convert.
My guess is that the annotation would introduce a wrapper function with the catching code block that would call the original function. The annotation would then only have compile-time-retension (and not run-time-retension).
I don't advocate that its wise to do this, it probably isn't because these annotations change the program semantics. It may well be an academical question to "just learn"...
Annotations don't do anything at all by themselves. You need a tool that evaluates them and does some code changing according to them.
In your case, AspectJ seems to be the best match.
My advice would be to read AspectJ in Action (2nd ed) by Ramnivas Laddad.
As you can see from it's Table of Content, it contains a chapter about exception softening, which is almost exactly what you want.
And since you tagged this question dependency-injection, assuming you use Spring, here is Spring's own Exception translation mechanism
Yes, this should be possible by creating an annotation processor that uses the compiler tree api (javac.tree package) to manipulate the source code while it's being compiled.
The problem is of course that this annotation processor now must be present whenever the code is compiled, and many tools that process source code (most prominently IDEs) may not know about it and consider the code invalid.

Refactoring advice and tools

I have some code that consists of a lot (several hundreds of LOC) of uggly conditionals i.e.
SomeClass someClass = null;
if("foo".equals(fooBar)) {
// do something possibly involving more if-else statments
// and possibly modify the someClass variable among others...
} else if("bar".equals(fooBar)) {
// Same as above but with some slight variations
} else if("baz".equals(fooBar)) {
// and yet again as above
}
//... lots of more else ifs
} else {
// and if nothing matches it is probably an error...
// so there is some error handling here
}
// Some code that acts on someClass
GenerateOutput(someClass);
Now I had the idea of refactoring this kind of code something along the lines of:
abstract class CheckPerform<S,T,Q> {
private CheckPerform<T> next;
CheckPerform(CheckPerform<T> next) {
this.next = next;
}
protected abstract T perform(S arg);
protected abstract boolean check(Q toCheck);
public T checkPerform(S arg, Q toCheck) {
if(check(toCheck)) {
return perform(arg);
}
// Check if this CheckPerform is the last in the chain...
return next == null ? null : next.checkPerform();
}
}
And for each if statment generate a subclass of CheckPerform e.g.
class CheckPerformFoo extends CheckPerform<SomeInput, SomeClass, String> {
CheckPerformFoo(CheckPerform<SomeInput, SomeClass, String> next) {
super(next);
}
protected boolean check(String toCheck) {
// same check as in the if-statment with "foo" above"
returs "foo".equals(toCheck);
}
protected SomeClass perform(SomeInput arg) {
// Perform same actions (as in the "foo" if-statment)
// and return a SomeClass instance (that is in the
// same state as in the "foo" if-statment)
}
}
I could then inject the diffrent CheckPerforms into eachother so that the same order of checks are made and the corresponding actions taken. And in the original class I would only need to inject one CheckPerform object. Is this a valid approach to this type of problem? The number of classes in my project is likely to explode, but atleast I will get more modular and testable code. Should I do this some other way?
Since these if-else-if-...-else-if-else statments are what I would call a recurring theme of the code base I would like to do this refactoring as automagically as possible. So what tools could I use to automate this?
a) Some customizable refactoring feature hidden somewhere in an IDE that I have missed (either in Eclipse or IDEA preferably)
b) Some external tool that can parse Java code and give me fine grained control of transformations
c) Should I hack it myself using Scala?
d) Should I manually go over each class and do the refactoring using the features I am familiar with in my IDE?
Ideally the output of the refactoring should also include some basic test code template that I can run (preferably also test cases for the original code that can be run on both new and old as a kind of regression test... but that I leave for later).
Thanks for any input and suggestions!
What you have described is the Chain of Responsibility Pattern and this sounds like it could be a good choice for your refactor. There could be some downsides to this.
Readability Because you are going to be injecting the the order of the CheckPerformers using spring or some such, this means that it is difficult to see what the code will actually do at first clance.
Maintainence If someone after you wants to add a new condition, as well as adding a whole new class they also have to edit some spring config. Choosing the correct place to add there new CheckPerformer could be difficult and error prone.
Many Classes Depending on how many conditions you have and how much repeated code within those conditions you could end up with a lot of new classes. Even though the long list of if else its very pretty, the logic it in one place, which again aids readability.
To answer the more general part of your question, I don't know of any tools for automatic refactoring beyond basic IDE support, but if you want to know what to look for to refactor have a look at the Refactoring catalog. The specific of your question are covered by replace conditional with Polymorphism and replace conditional with Visitor.
To me the easiest approach would involve a Map<String, Action>, i.e. mapping various strings to specific actions to perform. This way the lookup would be simpler and more performant than the manual comparison in your CheckPerform* classes, getting rid of much duplicated code.
The actions can be implemented similar to your design, as subclasses of a common interface, but it may be easier and more compact to use an enum with overridden method(s). You may see an example of this in an earlier answer of mine.
Unfortunately I don't know of any automatic refactoring which could help you much in this. Earlier when I did somewhat similar refactorings, I wrote unit tests and did the refactoring step-by-step, manually, using automated support at the level of Move Method et al. Of course since the unit tests were pretty similar to each other in their structure, I could reuse part of the code there.
Update
#Sebastien pointed out in his comment, that I missed the possible sub-ifs within the bigger if blocks. One can indeed use a hierarchy of maps to resolve this. However, if the hierarchy starts to be really complex with a lot of duplicated functionality, a further improvement might be to implement a DSL, to move the whole mapping out of code into a config file or DB. In its simplest form it might look something like
foo -> com.foo.bar.SomeClass.someMethod
biz -> com.foo.bar.SomeOtherClass.someOtherMethod
baz -> com.foo.bar.YetAnotherClass.someMethod
bar -> com.foo.bar.SomeOtherClass.someMethod
biz -> com.foo.bar.DifferentClass.aMethod
baz -> com.foo.bar.AndAnotherClass.anotherMethod
where the indented lines configure the sub-conditions for each bigger case.

Java exception handling idioms ... who's right and how to handle it?

I currently have a technical point of difference with an acquaintance. In a nutshell, it's the difference between these two basic styles of Java exception handling:
Option 1 (mine):
try {
...
} catch (OneKindOfException) {
...
} catch (AnotherKind) {
...
} catch (AThirdKind) {
...
}
Option 2 (his):
try {
...
} catch (AppException e) {
switch(e.getCode()) {
case Constants.ONE_KIND:
...
break;
case Constants.ANOTHER_KIND:
...
break;
case Constants.A_THIRD_KIND:
...
break;
default:
...
}
}
His argument -- after I used copious links about user input validation, exception handling, assertions and contracts, etc. to back up my point of view -- boiled down to this:
"It’s a good model. I've used it since me and a friend of mine came up with it in 1998, almost 10 years ago. Take another look and you'll see that the compromises we made to the academic arguments make a lot of sense."
Does anyone have a knock-down argument for why Option 1 is the way to go?
When you have a switch statement, you're less object oriented. There are also more opportunities for mistakes, forgetting a "break;" statement, forgetting to add a case for an Exception if you add a new Exception that is thrown.
I also find your way of doing it to be MUCH more readable, and it's the standard idiom that all developers will immediately understand.
For my taste, the amount of boiler plate to do your acquaintance's method, the amount of code that has nothing to do with actually handling the Exceptions, is unacceptable. The more boilerplate code there is around your actual program logic, the harder the code is to read and to maintain. And using an uncommon idiom makes code more difficult to understand.
But the deal breaker, as I said above, is that when you modify the called method so that it throws an additional Exception, you will automatically know you have to modify your code because it will fail to compile. However, if you use your acquaintance's method and you modify the called method to throw a new variety of AppException, your code will not know there is anything different about this new variety and your code may silently fail by going down an inappropriate error-handling leg. This is assuming that you actually remembered to put in a default so at least it's handled and not silently ignored.
the way option 2 is coded, any unexpected exception type will be swallowed! (this can be fixed by re-throwing in the default case, but that is arguably an ugly thing to do - much better/more efficient to not catch it in the first place)
option 2 is a manual recreation of what option 1 most likely does under the hood, i.e. it ignores the preferred syntax of the language to use older constructs best avoided for maintenance and readability reasons. In other words, option 2 is reinventing the wheel using uglier syntax than that provided by the language constructs.
clearly, both ways work; option 2 is merely obsoleted by the more modern syntax supported by option 1
I don't know if I have a knock down argument but initial thoughts are
Option 2 works until your trying to catch an Exception that doesn't implement getCode()
Option 2 encourages the developer to catch general exceptions, this is a problem because if you don't implement a case statement for a given subclass of AppException the compiler will not warn you. Ofcourse you could run into the same problem with option 1 but atleast option 1 does not activly encourage this.
With option 1, the caller has the option of selecting exactly which exception to catch, and to ignore all others. With option 2, the caller has to remember to re-throw any exceptions not explicitly caught.
Additionally, there's better self-documentation with option 1, as the method signature needs to specify exactly which exceptions are thrown, rather than a single over-riding exception.
If there's a need to have an all-encompassing AppException, the other exception types can always inherit from it.
The knock-down argument would be that it breaks encapsulation since I now I have to know something about the subclass of Exception's public interface in order to handle exceptions by it. A good example of this "mistake" in the JDK is java.sql.SQLException, exposing getErrorCode and getSQLState methods.
It looks to me like you're overusing exceptions in either case. As a general rule, I try to throw exceptions only when both of the following are true:
An unexpected condition has occurred that cannot be handled here.
Somebody will care about the stack trace.
How about a third way? You could use an enum for the type of error and simply return it as part of the method's type. For this, you would use, for example, Option<A> or Either<A, B>.
For example, you would have:
enum Error { ONE_ERROR, ANOTHER_ERROR, THIRD_ERROR };
and instead of
public Foo mightError(Bar b) throws OneException
you will have
public Either<Error, Foo> mightError(Bar b)
Throw/catch is a bit like goto/comefrom. Easy to abuse. See Go To Statement Considered Harmful. and Lazy Error Handling
I think it depends on the extent to which this is used. I certainly wouldn't have "one exception to rule them all" which is thrown by everything. On the other hand, if there is a whole class of situations which are almost certainly going to be handled the same way, but you may need to distinguish between them for (say) user feedback purposes, option 2 would make sense just for those exceptions. They should be very narrow in scope - so that wherever it makes sense for one "code" to be thrown, it should probably make sense for all the others to be thrown too.
The crucial test for me would be: "would it ever make sense to catch an AppException with one code, but want to let another code remain uncaught?" If so, they should be different types.
Each checked Exception is an, um, exception condition that must be handled for the program behavior to be defined. There's no need to go into contractual obligations and whatnot, it's a simple matter of meaningfulness. Say you ask a shopkeeper how much something costs and it turns out the item is not for sale. Now, if you insist you'll only accept non-negative numerical values for an answer, there is no correct answer that could ever be provided to you. This is the point with checked exceptions, you ask that some action be performed (perhaps producing a response), and if your request cannot be performed in a meaningful manner, you'll have to plan for that reasonably. This is the cost of writing robust code.
With Option 2 you are completely obscuring the meaning of the exception conditions in your code. You should not collapse different error conditions into a single generic AppException unless they will never need to be handled differently. The fact that you're branching on getCode() indicates otherwise, so use different Exceptions for different exceptions.
The only real merit I can see with Option 2 is for cleanly handling different exceptions with the same code block. This nice blog post talks about this problem with Java. Still, this is a style vs. correctness issue, and correctness wins.
I'd support option 2 if it was:
default:
throw e;
It's a bit uglier syntax, but the ability to execute the same code for multiple exceptions (ie cases in a row) is much better. The only thing that would bug me is producing a unique id when making an exception, and the system could definitely be improved.
Unnecessary have to know the code and declare constants for the exception which could have been abstract when using option 1.
The second option (as I guess) will change to traditional (as option 1) when there is only one specific exception to catch, so I see inconsistencey over there.
Use both.
The first for most of the exceptions in your code.
The second for those very "specific" exceptions you've create.
Don't struggle with little things like this.
BTW 1st is better.

In Java how would you write the equivalent of Iterable which could throw exceptions?

In java a class can implement Iterable which lets you use the foreach() statement and the iteration syntatic sugar:
for(T t:ts) ...
However, this does not allow you to throw exceptions on the construction for an Iterator. If you were iterating off a network, file, database etc it would be nice to be able to throw exceptions. Obvious candidates are java.io.InputStream, Reader and the java.nio.Channel code, but none of this can use Generics like the Iterable interface can.
Is there a common idiom or Java API for this situation?
Clarification: This is asking if there is a pattern or alternative interface for iterating for objects off a non-memory source. As responders have said, just throwing RuntimeExceptions to get around the problem is not recommended or what I was looking for.
Edit 2: Thanks to answers so far. The consensus seems to be "you can't". So can I extend the question to "What do you do in this situation, when this situation would be useful?" Just write your own interface?
Unfortunately you can't. There are two problems:
The Iterator API doesn't declare any exceptions to be thrown, so you'd have to throw RuntimeExceptions (or non-Exception throwables)
The enhanced for loop doesn't do anything to try to release resources at the end of the loop
This is very annoying. In C#, for instance, you can really easily write code to iterate through the lines of a text file:
public static IEnumerable<string> ReadLines(string filename)
{
using (TextReader reader = File.OpenText(filename))
{
string line;
while ( (line=reader.ReadLine()) != null)
{
yield return line;
}
}
}
Use as:
foreach (string line in ReadLines("foo.txt"))
The foreach loop calls Dispose on the IEnumerator in a finally block, which translates to "check if we need to do anything in the iterator block's finally (from the using statement)". Obviously there are no checked exceptions in C#, so that side of things isn't a problem either.
A whole (useful!) idiom is pretty much unworkable in Java due to this.
Streams like a network aren't really iterable in the traditional sense. Data can come through at any time, so it doesn't make sense to have a for each loop.
For a file read, or a DB snapshot (like a select query) there's no reason you can't take that data, segment it into logical chunks and implement an iterable interface.
You can also call an initialize method first that will catch any exceptions, if that's an issue.
try{
ts.initializeIOIterator();
}catch(...)
for(T t:ts)
...
Best what you can do is to create RuntimeIOException which you will throw from your hasNext/next implementation in case of errors.
try {
for (...) {
// do my stuff here
}
catch (RuntimeIOException e) {
throw e.getCause(); // rethrow IOException
}
RuntimeIOException will be runtime exception, wrapping your IOException:
class RuntimeIOException extends RuntimeException {
RuntimeIOException(IOException e) {
super(e);
}
IOException getCause() {
return (IOException) super.getCause();
}
}
Sometimes there is no other way.
I'd say you can't, even if you could you probably shouldn't. You get bytes from these things, if they were used in a for loop likely every byte would end up boxed.
What you can do is wrap checked exceptions in unchecked exceptions and comply to the iterable interface, though again this isn't advisable.
Generally in this situation, I would throw an appropriate subclass of RuntimeException in the Iterable's implementation.
In terms of cleaning up resources, a try - finally block works just as well wrapping a foreach block as it does around any other bit of code, so from the client's perspective it can easily use this to clean up any resources. If you want to manage resources within the Iterable it can be trickier, since there's no obvious start and finish lifecycle points.
In this case the best you could probably do is to create the resources on demand (i.e. the first call to next()), and then destroy them either when a call to next() is about to return false, or when an exception is thrown in the body of next(). Doing this would of course mean that when your next() method exits with an exception, the iterator can no longer be used - this is not an unreasonable constraint to place (consider the exception a more error-y version of returning false) but is something you should document as this isn't strictly covered by the interface.
That said, the above assumes that you're creating something solely as an Iterable. I find that in practice, when I implement Iterable on a class, it's more like a "super-getter" (i.e. a way for clients to conveniently access the information stored within it), than it is the point of the class itself. Most of the time these objects will be set up independently and accessed via other methods, so their lifecycle can be managed completely separately from their existence as an Iterable.
This might seem tangential to the question, but the immediate answer to the question is straightforward ("use runtime exceptions") - the tricky part is maintaining an appropriate state in the presence of these exceptions.

Categories

Resources