Clarify what is asked for in java Exceptions assignment - java

The requirements of the following java assignment are unclear to me. Does anyone understand what is needed?
Assignment: In the previous assignment, you implemented a stack and a list that both inherited from the abstract class ArrayIntCollection. In this next task you are supposed to extend that implementation by making it throw exceptions. If you try to perform operations that are not allowed (for example, if you try to call pop or peek on an empty stack or try to remove an element from a non existing position) you shall create and use the exception class CollectionException of the type UncheckedException. Also write a test program ExceptionMain.java that generates and catches exceptions from your modified methods.
The way I understand it, I need to create an exception class called CollectionException. This class needs to extend UncheckedException. (This part is not working, as I cannot find a class called UncheckedException).
Also, it is apparent whether I am to use try\catch or throw for this task?
Thanks to all!

...by make it throw exceptions...
will mean, yes, you have to use throw.
Also write a test program ExceptionMain.java that generates and catches exceptions from your modified methods.
At least here you will have to use try...catch.
Regarding "UncheckedException": Either there is a class of this name (perhaps in another package). Then you can ask your teacher where it is. Otherwise you can extend from java.lang.RuntimeException (which is an unchecked exception) and ask you teacher if that's OK.

Related

Which exception to throw if a method is called again when it must only be called once?

I have a class which offers a public method that must only be called once.
What would be a proper exception to throw in case its called again?
My current candiate is RejectedExecutionException
IllegalStateException may be appropriate, or something similar. For example, calling Thread::start twice would throw IllegalThreadStateException.
I suggest something completely different:
Consider if you can change your design.
The fact that your interface allows to only call a method once puts a constraint on the users of your interface. Interfaces should make it easy to use them "the right way"; and make it hard to use them the wrong way.
So instead of thinking about the exception type to throw ... think about solutions to simply make it impossible to misuse the interface.
For example, make the method private - and invoke only within the constructor of some internal singleton object. That (more or less) guarantees that the method will be called exactly once.

Should I declare all exceptions thrown from a method in the method signature or just the super class of the exceptions?

When I throw checked exceptions from a method should I just declare the super class of the exceptions in the method signature or all the different types? If I have the following exceptions:
private class SuperException extends Exception {
}
private class SubExceptionOne extends SuperException {
}
private class SubExceptionTwo extends SuperException {
}
Should the method signature be:
void confirmAccount() throws SubExceptionOne, SubExceptionTwo;
or
void confirmAccount() throws SuperException;
In the last method signature, how do I tell other developers what exceptions that could be thrown from the method? If the different sub types need different handling?
The interface should be as stable as possible. So probably Super. Many libraries use the "Super" strategy, because exception specs cause far more annoyance in maintainability than readability or safety they add. Even the IOException is a Super that nearly all Java library code uses instead of declaring more specific exceptions. (But when they do declare more specific exceptions, it's because the contract is that more general IOExceptions won't be thrown. Read on.)
You might list Sub1 and Sub2 if you really do want to say each of those exceptions can be thrown, but don't want to say that any derivative of Super can be thrown. Perhaps Sub1 is NumberCrunchException and your method calls crunchNumbers() and users of your method can be assured that's the only exception-ful thing your method does. In that case the specific strategy is better.
If the different sub types need different handling, then definitely declare the two different exceptions. Never expect the developer using your method to guess that you are actually throwing different types of exceptions.
If you declare two distinct exceptions, and the user knows from the Javadoc that they are actually descendents of the same class, the user may choose to catch them both with a catch (SuperException e) rather than two individual catch clauses. But it depends on the user's choice.
If you don't declare them separately, your IDE is not going to add the appropriate #Throws to your Javadoc comment. And your Javadoc will therefore only indicate that you're throwing SuperException, which will leave the user in the dark. Solving this by just putting it in the text of the comment is not a real solution. If any tool is using reflection to determine what your method throws, it will not see the individual exceptions in the array returned from Method.getExceptionTypes().
If the functionality expected of the different exceptions is more or less the same and it's just a matter of how they will appear in the logs, it may be better to just use the parent exception, with different messages.
The throws clause is there to convey useful information to the calling method about what might go wrong during invocation of this method. That means that how specific you are will depend on how much information you want to convey; and that will be application-dependent.
For instance, declaring throws Exception is almost always a bad idea: the information this conveys is just "something might go wrong", which is too vague to be useful. But whether calling classes are going to need perfectly fine-grained information in the throws clause is something you need to decide by looking at your program. There's no set answer.

Programmatically distinguish exceptions

The type of an exception is often enough to handle it properly (for example you try to open a file and get a FileNotFoundException). However there are cases where you might catch multiple exception of the same type. For example, an IllegalArgumentException that can be caused by more than one argument. The IllegalArgumentException does not add any additional methods (or public fields) to the Throwable interface (accoding to the online javadoc) which means that the only information that you can rely on are the nested exception (which may or may not exist) and the message (which is for human consumption).
I don't like the idea of extending IllegalArgumentException to add structured information to it, because other people would have to learn the new class. And I don't like the idea of littering projects with very specific exception classes.
Using the message field is also a bad idea because it's not meant for programmatic access.
I think IllegalArgumentException should have included details such as the class function and argument(s) in question. And in general custom exceptions should provide additional detail (other then just their type) for a more fine grained exception handling.
What are considered generally the best practices for designing exception classes, and handling exceptions of the same type?
As a general rule, I think it is ideal to have one class of exception per "type of action a caller might reasonably want to take". Of course, for one's own custom exceptions there could be a boolean or enum field providing some extra disambiguation, rather than creating trivial subclasses.
In your specific case I'm not convinced that trying to handle the exception is a good idea. RuntimeException and its subclasses usually represent coding issues, and the same is true of IllegalArgumentException. If the argument is illegal it shouldn't be passed in in the first place.
If you're in a situation where you're not sure if an argument is valid (maybe it's user input, or maybe you don't know the specific object you're calling the method on) then a better approach would be to have some way of checking the validity of the argument before passing it. Rather than say "do this" and catch the exception, ask "can I do this?" before calling.
Exception classes should be designed so as to provide all that is needed when they are caught. Note that try/catch statements are actually a form of type switch, so in general it is cleaner to create additional exception classes rather than confuse program logic by nesting too many if's within catch clauses.
It has to be said that catch clauses are not very convenient if you want to organize your error handling code in an object oriented fashion, so there are different trade offs to keep in mind.
Note that standard exception classes do have information available on what piece of code caused the exception, even though I would not advise you to base on it your error handling logic.
If the current exception was thrown in a catch clause for a different exception this should be available with the getCause() method, while the getStackTrace() should provide access to the stack of calls that were active when your exception was thrown.
Again I don't advise you to use this information except for debugging purposes.
Its true that the predefined exception classes are very general. But if you want more specific details about the exceptions then you should go for user defined exceptions. you should create your own exception classes with any level of details!
here is the pseudo code:
public class TooManyArguments extends exception{
public String toString(){
return ("..whatever information you want to give for this exception..")'
}
}
and whenever you encounter exceptional situation throw an instance of this class
throw new TooManyArguments();

Java: Exception in constructors: Problematic or not?

I am recently thinking about if throwing constructor from Java is good or not. Currently this is what I gathered:
Can constructors throw exceptions in Java?
Here, Mr. StackOverflow (aka Jon Skeet) does not seem to hold anything against it, but he did hint about having subclass throwing exceptions. What will happen (anything bad?) when subclass throws exceptions?
http://futuretask.blogspot.com/2006/05/java-tip-10-constructor-exceptions-are.html
This blog post "Constructor Exceptions are Evil" tells me a way to show that constructor exceptions could be dangerous. However, the example seem to be really esoteric. Is there any real danger here?
I am thinking that if static factory methods (Effective Java 2nd ed., Item 1) are used instead of public constructors, we could safely remove the exceptions from constructors to the static factory method. Is this a valid way to avoid constructor exceptions and is this useful or used in anywhere?
Any inputs are helpful & appreciated. Thanks!
There is nothing wrong with exceptions in constructors (or factory methods, either way is fine). sometimes, doing too much work in a constructor can be a poor design, and may make sense to move to a factory method.
the only thing that point 2 proves is that exceptions in constructors are not an adequate security mechanism for protecting a class from evil usage. however, there are any number of ways to subvert such a design, which is why the only way to truly run secure code in java is running with a SecurityManager. so point 2 is just a straw man argument.
My point about a subclass throwing an exception is a situation like this:
public class Parent {
private final InputStream stream;
public Parent() {
stream = new FileInputStream(...);
}
public void close() throws IOException {
stream.close();
}
}
public class Child extends Parent {
public Child() {
// Implicit call to super()
if (someCondition) {
throw new RuntimeException();
}
}
}
Now the Child class really should call close() if it's going to throw an exception. Of course, if close() is overridden by yet another layer of inheritance, that could also cause problems. Just another example of how inheritance gets messy.
I still think it's basically fine for constructors to throw exceptions. Even your second link was more about an evil way of capturing the not-successfully-constructed object rather than really about constructor exceptions being evil - it certainly doesn't give any reasons for not throwing exceptions from constructors. It doesn't even give the messy situation I mentioned.
Factory methods could potentially help, but as far as the caller is concerned the result is the same: they don't get to see the partially-constructed object. Unless you really need to do something like clean-up on an object which was constructed but then failed some element of validation, I don't think that should be a reason to use factory methods instead of constructors. (There are other reasons to do so, but that's a different matter.)
I believe throwing exceptions from constructors is fine, more so the one's which checks for the preconditions to a successful object creation, example IllegalArgumentException.
However, I do not believe that constructors are the right place to handle business logic or throw business exception/ custom exceptions.
As for the reasons cited to not throw an exception, IMHO they are quite contrived; bottom line is if a careless developer wishes to do something evil he can find numerous ways to do it and there's no stopping till the developer does a self review of the code/ follows best practices.

Exception handling when overridden method does not throw any exception

Short form: How do you throw exceptions (or do nice, clean exception handling; or at least dirtily force execution to stop) when the overridden method doesn't throw exceptions?
Context: We have a license for a piece of proprietary software that can be automated using Java "macros". A user-defined macro must be of this form:
public class MyMacro extends SoftwareMacro {
public void execute() {
// user code goes here
}
}
i.e. a class that extents SoftwareMacro and that has a method called execute that overrides the base class' execute. The contents of this overriding execute are what gets... well... executed when the macro is "played".
But the overridden execute method apparently does not throw any exceptions.
execute() in com.mycompany.mypackage.MyMacro cannot implement execute() in
somesoftware.base.SoftwareMacro
overridden method does not throw java.lang.Exception
Maybe this is naïve, but while developing I usually like to have the appropriate exception type bubble up to the top and force execution to stop, so that I can see them and go on to debug. This is apparently not an option here.
Should I resort to throwing RuntimeException instead? (since RuntimeException does not need to be specified) That feels a bit sloppy, and a "violation in spirit" of the base class method contracy.
P.S. No, I can't change the source code of the overriden execute method.
Looks like the intent is that each SoftwareMacro do all its own error handling. Use a big try around your whole execute() method if need be, but don't let any exceptions escape. Do whatever cleanup you need to do inside your execute method, and possibly print an error message for the user, if they provide a way to do that.
You should examine all the APIs they provide -- perhaps there's an error reporting facility you're supposed to use.
It all depends on what the "Macro player" does if it encounters a runtime exception, and on what you want to happen.
If it doesn't handle it at all, but you don't care, throw a RuntimeException.
If it handles them properly, throw a RuntimeException.
If it doesn't handle them properly, and you don't want it to fail miserably, then catch the exceptions that might happen in your execute method, and handle them as you feel is the best: show an error dialog box, output an error message, log some error in the logs...
"Should" implies there's a right answer, which IMO there isn't do what meets your needs.
If the system can tolerate a runtime exception, and it meets your needs, why not?
Not that you have a choice, since you can't throw a checked exception.
(Checked exceptions seem like a failed experiment to me, although I understand the motivation.)
So long as the execute code doesn't absorb the exception, it will still throw it if one is encountered. If the kind of exceptions thrown are either RuntimeException or sub-classes of RuntimeException they don't need to be explicitly declared, mostly because the compiler doesn't enforce their declaration since (as the name implies) they only happen at runtime, and cannot necessarily be predicted at compile time.
If, however, the execute method, which you've said you can't modify, absorbs the exception, and doesn't indicate that exception via a log entry, return value, or some kind of RuntimeException I think you're out of luck.
I would agree with Ernest that it appears that the intent is that the execute method do all its own exception handling.
NOTE: Overridden method signatures don't need to match exactly when it comes to the exceptions they throw - just the name, return type, and list & type of variables.

Categories

Resources