This is my code:
public static void main(String[] args) throws Exception {
Scanner s = new Scanner(new File("story.txt"));
someFunction(s);
}
The story.txt is in the the project root, but without the throws Exception the code doesn't run.
Why?
You don't need throws Exception, but it won't hurt any if you leave it like that.
What you do need is a throws FileNotFoundException because the Scanner constructor you are using is declared to throw that exception, and you don't catch any exceptions.
You should throw a FileNotFoundException, because the Scanner constructor can throw one. Since it is a checked exception, you must either pass it further up the stack or handle it somehow.
I asked my professor, and he explained that Java makes you handle exceptions.
You must be ready for them if a function might throw them.
You can either use:
try {...
} catch { ...
}
to handle exceptions yourself, or you can use:
throws Exceptions
to "pass them to the next level" (handle them later).
Thanks for the help!
If a method or constructor either throws an exception which isn't derived from RuntimeException, or calls any method whose declaration indicates it must do so, then it must either catch that exception or declare that the exception may be thrown from it. This language feature is almost a good thing, but in its present form has been widely acknowledged as a mistake. Nonetheless, it is sufficiently firmly established as part of the Java language that it's not going anywhere.
Conceptually, it's good to make a distinction between exceptions which are likely to have special meaning to a method's immediate caller and those which would not. Unfortunately, the fact that an exception would have a special meaning to its immediate caller doesn't mean the immediate caller is going to be interested in it. The way Java implements checked exceptions, if Foo is declared as throwing a checked exception and Bar calls Foo but isn't prepared to handle that exception, it must either declare itself as throwing that exception (even though it's unlikely to have any special meaning to its caller), or else catch the exception it has no hope of handling (perhaps rethrowing as a type derived from RuntimeException). Catching and rethrowing as a type derived from RuntimeException is semantically the best approach, but ends up being the most verbose, especially if one wants to avoid making RuntimeException objects.
Note also that because there's no way a chained constructor call can be wrapped in a try block, any constructor which is chained through a constructor that is declared as throwing any exceptions is required to declare itself as throwing those same exceptions. Things are implemented that way for a reason, but it unfortunately makes it difficult for a class constructor to distinguish exceptions which got thrown as part of the base-class construction process and those which got thrown in the construction of the derived class.
Because, Scanner s = new Scanner(new File("story.txt")); throws checked FileNotFoundException. You should throws or catch checked exception for compilation.
Related
The below picture shows that "Checked" and "Unchecked" Exceptions are subclasses of Exception. I find it confusing that you need to catch an Exception but you don't need to catch a RuntimeException, which directly inherits from Exception. Is there a reason that the devs didn't let us throw Exceptions without needing to catch them?
More specifically: Why can you ignore only RuntimeExceptions and it's children? Why wasn't there a Class introduced called CheckedException extends Exception and you only need to catch it and it's children?
The confusing part is, that you can throw everything below RuntimeException without issue, but when you move up to Exception in the hierarchy, you need to catch it at some point. This is confusing because "abstraction" normally works otherwise. The more you move up, the simpler and more meta everything gets. This is not the case here. The more you move up, the more you have to do (like, putting try/catch after reaching Exception).
If Exception was unchecked then you could implicitly cast checked exceptions to unchecked ones, which would mean that you could throw checked exceptions without catching them like:
public void f() {
Exception e = new IOException();
throw e;
}
and also with overriding methods, if you throw a more specific exception, you can add the requirement to catch the exception that wasn't in the superclass:
public void f() throws Exception {
}
...
#Override
public void f() throws IOException {
}
Suppose they designed it the other way. We have a CheckedException class, and subclasses of that need to be handled, but not other subclasses of Exception.
Now we call a method that might throw an arbitrary Exception:
public static void example() {
functionThatThrowsException();
}
Do we need to handle it? Yes, because that Exception might be a CheckedException. If we didn't need to handle it, we'd be bypassing the checked nature of checked exceptions.
A throwable type with checked descendants must be treated as checked, so checkedness naturally propagates up the inheritance hierarchy. Contrapositively, an unchecked throwable type cannot have checked descendants, so uncheckedness naturally propagates down. This makes it natural to make checkedness the default, and single out specific classes and their descendants as unchecked.
CheckedException (Which does exist) and RuntimeException both extend Exception. Because of this, if something throws a generic Exception (which is always a bad idea), there is no way to tell if the exception could be one or the other, so you have to catch it in case it's a checked one. If you think of the hierarchy in this way, it actually does get simpler the farther up you go.
You seem to have the idea that checked exceptions are more "complex" because you have to do more to work around them. This isn't too healthy a way of thinking about it. Instead, consider this: Exceptions are problems with the program itself - the code. We need to find these exceptions and handle them properly. After already having this concept of exception handling, we discover that there are some problems that we simply can't predict.
"How was I supposed to know the user would enter 'meow' when asked for an integer! I shouldn't have to code around that!" And so, NumberFormatException was born, and you don't have to catch it because it's a "logical error", not an issue caused by bad code (Although, arguably, it might be considered bad code if you don't handle this situation in some way).
In short, reverse your thinking. Exceptions are problems with the program that can be handled. There are some exceptions, however, that are unexpected and are a result of bad design more than incorrect code. Thus there is the addition of RuntimeExceptions which cannot possibly be expected to occur, but certainly can occur.
Perhaps it would help to not think of exception classes in terms of inheritance but simply disjoint sets of classes, one set is checked and other is not. You're right that there could be a CheckedException class allowing us to check only when explicitly intended.
However having the broader/generalized range checked helps in enforcing the catch or specify pattern. Having checked exception allows a reader of the code to figure out quickly that this piece of code needs special attention and enforcing their handling at compile time reducing the runtime bugs.
We can throw any kind of exception, checked or unchecked. If Exception or any super class of RuntimeException were to be set as checked exception then all the sub classes would become checked exceptions. As compiler is most likely checking if an instance of exception or a class in the throws clause derives from a class. It could easily have done that by checking for a specific package which probably would have been more appropriate as being checked or unchecked has simply nothing to do with the inheritance.
Why throws, on a method, is part of its signature? It seems strange to include it. Here is an example where it is in the way:
#Overide
public void foo() {
throw new UnsupportedOperationException();
}
If anyone were to see this method from the outside, they might try to use it without knowing that it is not supported. They would only learn it on trying to run the code.
However, if they could do something like this they would know by looking at the method that it is not supported and if UnsupportedOperationException was not extending RuntimeException, they would get a compilation error. EDIT1: But this is not possible because throws is part of the signature so override will not work.
#Overide
public void foo() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
This question concerns Java's design, so I know that it might be hard to answer without one of the people that work on it drops by and answers it, but I was hoping that maybe this question has been asked to them before or that there might be an obvious reason to have it this way to explain why.
The throws part does not indicate that the method is required to throw the mentioned exception(s), not even at particular occasions. It only tells that the function is allowed to do so.
Including throws UnsupportedOperationException will consequently not mean that the method is unsupported. Besides the UnsupportedOperationException is a RuntimeException so a method may throw that anyway.
Now for the reason one would require it in the signature of the method, it boils down to the ability to have checked exceptions at all. For the compiler to be able to decide if a method can only throw the specified exceptions it must be able to decide that the methods that it calls can't throw uncaught exceptions.
This means for example that overriding a method means that you can't add exceptions that might be thrown, otherwise you would break the possibility to verify that a method that calls that method can't throw anything else than it has specified. The other way around would be possible (but I'm not sure if Java supports that), overriding a method that may throw with one that may not throw.
So for example:
class B {
int fubar(int) throws ExceptionA {
}
int frob(int) throws ExceptionA {
return fubar(int);
}
}
class D extends B {
int fubar(int) throws ExceptionB {
}
}
Now frob is specified to possibly throw only ExceptionA, but in calling this.fubar it would open the possibility that something else is thrown, but fubar is defined to possibly only throw ExceptionA. That's why the D.fubar is an invalid override since that would open up the possibility that this.fubar actually throws ExceptionB and the compiler wouldn't be able to guarantee that frob doesn't throw ExceptionB.
Java has two different types of exceptions: checked Exceptions and
unchecked Exceptions.
Unchecked exceptions are subclasses of RuntimeException and you don't have to add a throws declaration. All other exceptions have to be handled in the method body, either with a try/catch statement or with a throws declaration.
Example for unchecked exceptions: IllegalArgumentException that is used sometimes to notify, that a method has been called with illegal arguments. No throws needed.
Example for checked exceptions: IOException that some methods from the java.io package might throw. Either use a try/catch or add throws IOException to the method declaration and delegate exception handling to the method caller.
One thing which no one has mentioned is a very important answer to your question:
Why throws, on a method, is part of its signature?
that throws, is NOT part of the method signature.
JLS 8.4.2. Method Signature makes it quite clear, that:
Two methods or constructors, M and N, have the same signature if they have the same name, the same type parameters (if any) (ยง8.4.4), and, after adapting the formal parameter types of N to the type parameters of M, the same formal parameter types.
If anyone were to see this method from the outside, they might try to use it without knowing that it is not supported.
That's exactly the main reason, why throws is designed in a way to be checked at compile-time for all Checked Exceptions - clients of the method will be aware what this method may possibly throw.
Checked Exceptions are enforced to be either handled or specified to be thrown (but this specification is NOT part of the method signature).
Unchecked Exceptions do not have to be either handled or specified to be thrown, and Oracle's tutorial are good at explaining - why:
Runtime exceptions represent problems that are the result of a programming problem, and as such, the API client code cannot reasonably be expected to recover from them or to handle them in any way. Such problems include arithmetic exceptions, such as dividing by zero; pointer exceptions, such as trying to access an object through a null reference; and indexing exceptions, such as attempting to access an array element through an index that is too large or too small.
For example:
FileWriter saveFile = new FileWriter("text.txt");
This code shows the error:
Unhandled exception type IOException
What does this mean?
Java has checked exception mechanism.
It means every exception (which is not RuntimeException) that is thrown by a method must be handled by the method internally or be declared the is throwing it (in its declaration).
In your example, the constructor of FileWriter is throwing IOException, so you should either handle it internally in the method by try-catch blocks, or make your method's signature declared it might throw it.
There are exceptions which Java compiler forces to be handled by developer & need properly propagated to caller.
These exceptions fall under the category of checked exception(compile time exceptions).
Either with try{...}catch{...} or with throws keyword these type of exceptions must be handled by developer.
The class Exception and any subclasses that are not also subclasses of RuntimeException are checked exceptions. Visit java doc here
Are constructors allowed to throw exceptions?
Yes, constructors can throw exceptions. Usually this means that the new object is immediately eligible for garbage collection (although it may not be collected for some time, of course). It's possible for the "half-constructed" object to stick around though, if it's made itself visible earlier in the constructor (e.g. by assigning a static field, or adding itself to a collection).
One thing to be careful of about throwing exceptions in the constructor: because the caller (usually) will have no way of using the new object, the constructor ought to be careful to avoid acquiring unmanaged resources (file handles etc) and then throwing an exception without releasing them. For example, if the constructor tries to open a FileInputStream and a FileOutputStream, and the first succeeds but the second fails, you should try to close the first stream. This becomes harder if it's a subclass constructor which throws the exception, of course... it all becomes a bit tricky. It's not a problem very often, but it's worth considering.
Yes, they can throw exceptions. If so, they will only be partially initialized and if non-final, subject to attack.
The following is from the Secure Coding Guidelines 2.0.
Partially initialized instances of a non-final class can be accessed via a finalizer attack. The attacker overrides the protected finalize method in a subclass, and attempts to create a new instance of that subclass. This attempt fails (in the above example, the SecurityManager check in ClassLoader's constructor throws a security exception), but the attacker simply ignores any exception and waits for the virtual machine to perform finalization on the partially initialized object. When that occurs the malicious finalize method implementation is invoked, giving the attacker access to this, a reference to the object being finalized. Although the object is only partially initialized, the attacker can still invoke methods on it (thereby circumventing the SecurityManager check).
Absolutely.
If the constructor doesn't receive valid input, or can't construct the object in a valid manner, it has no other option but to throw an exception and alert its caller.
Yes, it can throw an exception and you can declare that in the signature of the constructor too as shown in the example below:
public class ConstructorTest
{
public ConstructorTest() throws InterruptedException
{
System.out.println("Preparing object....");
Thread.sleep(1000);
System.out.println("Object ready");
}
public static void main(String ... args)
{
try
{
ConstructorTest test = new ConstructorTest();
}
catch (InterruptedException e)
{
System.out.println("Got interrupted...");
}
}
}
Yes, constructors are allowed to throw exceptions.
However, be very wise in choosing what exceptions they should be - checked exceptions or unchecked. Unchecked exceptions are basically subclasses of RuntimeException.
In almost all cases (I could not come up with an exception to this case), you'll need to throw a checked exception. The reason being that unchecked exceptions (like NullPointerException) are normally due to programming errors (like not validating inputs sufficiently).
The advantage that a checked exception offers is that the programmer is forced to catch the exception in his instantiation code, and thereby realizes that there can be a failure to create the object instance. Of course, only a code review will catch the poor programming practice of swallowing an exception.
Yes.
Constructors are nothing more than special methods, and can throw exceptions like any other method.
Are constructors allowed to throw exceptions?
Yes, constructors can throw exceptions. Usually this means that the new object is immediately eligible for garbage collection (although it may not be collected for some time, of course). It's possible for the "half-constructed" object to stick around though, if it's made itself visible earlier in the constructor (e.g. by assigning a static field, or adding itself to a collection).
One thing to be careful of about throwing exceptions in the constructor: because the caller (usually) will have no way of using the new object, the constructor ought to be careful to avoid acquiring unmanaged resources (file handles etc) and then throwing an exception without releasing them. For example, if the constructor tries to open a FileInputStream and a FileOutputStream, and the first succeeds but the second fails, you should try to close the first stream. This becomes harder if it's a subclass constructor which throws the exception, of course... it all becomes a bit tricky. It's not a problem very often, but it's worth considering.
Yes, they can throw exceptions. If so, they will only be partially initialized and if non-final, subject to attack.
The following is from the Secure Coding Guidelines 2.0.
Partially initialized instances of a non-final class can be accessed via a finalizer attack. The attacker overrides the protected finalize method in a subclass, and attempts to create a new instance of that subclass. This attempt fails (in the above example, the SecurityManager check in ClassLoader's constructor throws a security exception), but the attacker simply ignores any exception and waits for the virtual machine to perform finalization on the partially initialized object. When that occurs the malicious finalize method implementation is invoked, giving the attacker access to this, a reference to the object being finalized. Although the object is only partially initialized, the attacker can still invoke methods on it (thereby circumventing the SecurityManager check).
Absolutely.
If the constructor doesn't receive valid input, or can't construct the object in a valid manner, it has no other option but to throw an exception and alert its caller.
Yes, it can throw an exception and you can declare that in the signature of the constructor too as shown in the example below:
public class ConstructorTest
{
public ConstructorTest() throws InterruptedException
{
System.out.println("Preparing object....");
Thread.sleep(1000);
System.out.println("Object ready");
}
public static void main(String ... args)
{
try
{
ConstructorTest test = new ConstructorTest();
}
catch (InterruptedException e)
{
System.out.println("Got interrupted...");
}
}
}
Yes, constructors are allowed to throw exceptions.
However, be very wise in choosing what exceptions they should be - checked exceptions or unchecked. Unchecked exceptions are basically subclasses of RuntimeException.
In almost all cases (I could not come up with an exception to this case), you'll need to throw a checked exception. The reason being that unchecked exceptions (like NullPointerException) are normally due to programming errors (like not validating inputs sufficiently).
The advantage that a checked exception offers is that the programmer is forced to catch the exception in his instantiation code, and thereby realizes that there can be a failure to create the object instance. Of course, only a code review will catch the poor programming practice of swallowing an exception.
Yes.
Constructors are nothing more than special methods, and can throw exceptions like any other method.