I'm reviewing a midterm I did in preparation for my final exam tomorrow morning. I got this question wrong, but there's no correct answer pointed out, and I neglected to ask the prof about it.
Consider the following code snippet:
public static void main(String[] args) throws FileNotFoundException
Which of the following statements about this code is correct?
The main method is designed to catch and handle all types of exceptions.
The main method is designed to catch and handle the FileNotFoundException.
The main method should simply terminate if the FileNotFoundException occurs.
The main method should simply terminate if any exception occurs.
I had chosen the second option.
Answer is number 4,
4.- The main method should simply terminate if any exception occurs.
The throws clause only states that the method throws a checked FileNotFoundException and the calling method should catch or rethrow it. If a non-checked exception is thrown (and not catch) in the main method, it will also terminate.
Check this test:
public class ExceptionThrownTest {
#Test
public void testingExceptions() {
try {
ExceptionThrownTest.main(new String[] {});
} catch (Throwable e) {
assertTrue(e instanceof RuntimeException);
}
}
public static void main(String[] args) throws FileNotFoundException {
dangerousMethod();
// Won't be executed because RuntimeException thrown
unreachableMethod();
}
private static void dangerousMethod() {
throw new RuntimeException();
}
private static void unreachableMethod() {
System.out.println("Won't execute");
}
}
As you can see, if I throw a RuntimeException the method will terminate even if the exception thrown is not a FileNotFoundException
Dude, a little late, but answer is Number 3.
Number 1 is false because it is not handling FileNotFoundException
Number 2 is false for the same reason.
Number 3 is true. If a FileNotFoundException is thrown, the main method will terminate.
Number 4 is false. It would not terminate in case of ANY exception. It would terminate only in case of unchecked exception or FileNotFoundException. If there are not other checked exceptions declared in the 'throws' clause, it means they are being handled within the method.
The main method is not catching any exceptions, instead it handles the FileNotFoundException by throwing it to the source which invoked the main method.
The system runtime launches the JVM classes, one specific class among the JVM classes invokes the main method.
The handling for the main method's throws is at the mercy of the JVM classes in that case.
You can read about it in the Java language specification provided by Oracle.
Additionally you can view the source code for some of the JVMs available out there, going that path though takes you away to other programming languages,OpenJdk.
I thought of sharing my small humbled research crust in that topic, hope it helps curious ones :)
I agree with some other answers that the correct answer to the question is option 3. Option 4 says:
The main method should simply terminate if any exception occurs.
Note the "any" in this option. Here's an example of code in which an exception occurs, but main() does not terminate:
public static void main(String[] args) throws FileNotFoundException {
try {
methodThatThrowsACheckedException();
} catch (SomeCheckedException e) {
// do something to handle this exception
}
}
In this code an exception occurs, but the method does not terminate, as it's been setup to handle this exception. If the exception were an uncaught UncheckedException, then the method would terminate, of course. The point of option 4, though, is that any counter-example invalidates it, since it says "any" exception occurs.
Option 3, however, limits this termination to only occur when the exception in the method's signature is thrown:
The main method should simply terminate if the FileNotFoundException occurs.
The reason option 3 makes more sense is because code like the following does not make sense in practice:
public static void main(String[] args) throws FileNotFoundException {
try {
methodThatThrowsFileNotFoundException();
} catch (FileNotFoundException e) {
// do something to handle this exception
}
}
It doesn't make much sense to declare that a method throws an exception, but catch that exception in the method (unless, perhaps, you re-throw it after doing something, in which case option 3 still holds, as the method terminates eventually).
With only the declaration of main(), it is impossible to say which answer is objectively correct. Any of the statements could be true, depending on the definition of the method.
The main method is designed to catch and handle all types of exceptions.
The main method is designed to catch and handle the FileNotFoundException.
Both of the above statements are true of the following:
public static void main(String[] args) throws FileNotFoundException {
while (true) {
try {
doSomething();
}
catch (Exception e) {}
}
}
The declared exception is never thrown by main(), but that is not an error; just pointless and misleading.
The main method should simply terminate if the FileNotFoundException occurs.
The main method should simply terminate if any exception occurs.
Both of the above statements are true of the following:
public static void main(String[] args) throws FileNotFoundException {
try {
doSomething();
}
catch (Exception e) {
return;
}
}
Of course, we can guess at the intention of the question based on what a decent and reasonable programmer might intend to communicate with this method signature. Which would be that they intend for the method to throw FileNotFoundException, and necessarily handle other checked Exceptions. We can also reasonably assume that "handle" does not just mean "process", but specifically that it will not (re-)throw such an exception.
These assumptions immediately rule out #1 and #2.
The remaining question is whether "simply terminate" includes throwing an exception, or only an explicit return/System.exit(). In the former case, both of #3 and #4 could still be true:
public static void main(String[] args) throws FileNotFoundException {
try {
doSomething();
}
catch (FileNotFoundException fnfe) {
throw fnfe;
}
catch (Exception e) {
return;
}
}
In the latter case, neither #3 nor #4 can be true while also satisfying the assumption that main() will throw FileNotFoundException.
In sum, the options are not worded well. If I had to pick an answer, it would be #3 based on the logic of MartinV's answer. My assumption would be that the word "should" in #3 was an unfortunate choice by the professor, and that something like "may" would have been a better option. It would also have been a good idea to use more precise language than "simply terminate" (and, arguably, "handle").
The answer is both 2 & 3.
2.The main method is designed to catch and handle the FileNotFoundException.
3.The main method should simply terminate if the FileNotFoundException occurs.
But if fails to handle the exception even though it is designed to handle it and the programs gets terminated abnormally.
throws keywords is used to make JVM handle the exceptions which we are lazy to handle, it compiles successfully but shows the exception during runtime(if u handle it in main method then it compiles and runs successfully).
4.The main method should simply terminate if any exception occurs.
Is not correct always because the exceptions which occurs may be handle in the main method.
1.The main method is designed to catch and handle all types of exceptions.Is incorrect as JVM doesn't handle unchecked exceptions.
Related
I am having trouble understanding how precise rethrow works in Java 7 and later versions. As pointed out in https://www.theserverside.com/tutorial/OCPJP-Use-more-precise-rethrow-in-exceptions-Objective-Java-7, in Java 7 and later versions we can use the throws clause, in a method declaration, with a comma-separated list of specific exceptions that the method could throw. If all these exceptions are subtypes of the general exception java.lang.Exception, we will be able to catch any of them in a catch block that catches this supertype, while letting client code (eg. a caller method) to know which of the possible subtypes exceptions actually occurred.
Initially, I thought that in order to let know client code which exception actually occurred, we needed to specify the list of specific exceptions in the throws clause. Nevertheless, in the following example the client code (the main() method) seems able to retrieve that information, even if we only specify the exception java.lang.Exception in the throws clause of the called method. Therefore, my question is:
Why the following code outputs the same, regardless of whether the throws clause of the method runException() is throws ExceptionA, ExceptionB or throws Exception ?
I am using Oracle JVM-12 in Eclipse. Thanks in advance!
class ExceptionA extends Exception{}
class ExceptionB extends Exception{}
public class RethrowingAndTypeChecking{
public static void runException(char what) throws Exception{
//public static void runException(char what) throws ExceptionA, ExceptionB{
try{
if(what == 'A')
throw new ExceptionA();
else if (what == 'B')
throw new ExceptionB();
}
catch(Exception e){
throw e;
}
}
public static void main (String args[]){
char ch;
for (int i=0;i<2;i++) {
if(i==0) ch='A';
else ch = 'B';
try{
runException(ch);
}
catch(ExceptionA e){
System.out.print("In main(), 'catch(ExceptionA e){}', caught exception: " + e.getClass());
}
catch(ExceptionB e){
System.out.print("In main(), 'catch(ExceptionB e){}', caught exception: " + e.getClass());
}
catch(Exception e){
System.out.print("In main(), 'catch(Exception e){}', caught exception: " + e.getClass());
}
System.out.println();
}
}
}
output:
In main(), 'catch(ExceptionA e){}', caught exception: class ExceptionA
In main(), 'catch(ExceptionB e){}', caught exception: class ExceptionB
What you're missing is the case where you need to handle those possible exceptions in different ways. Your code is catching individual exceptions, but it is, roughly speaking, performing the same action.
If you were to handle ExceptionA in a considerably different way from how you handle ExceptionB, then catching the broad Exception would not allow you to do that specifically:
catch(Exception e){
// something unexpected happened
// e could be an ExceptionA problem
// e could be an ExceptionB problem
// e could be any other unchecked exception
}
When the catch(Exception e){} block is entered, the exception could pretty much be anything, but you have only one generic code block to handle it.
Beside this, if the method you're calling declares specific checked exceptions, then the compiler can help you handle only those exceptions, thus adding to the predictability of the code
try{
runException(ch);
} catch(ExceptionA e){
// code specific to handling ExceptionA problems
} catch(ExceptionB e){
// code specific to handling ExceptionB problems
} catch(ExceptionC e){ //will not compile, because not declared by runException
// code specific to handling ExceptionB problems
}
Quoting #Carlos Heuberger, my code outputs the same, regardless of whether the throws clause of the method runException() is throws ExceptionA, ExceptionB or throws Exception because:
the run-time type of the exception is used to select the catch clause: see 14.20.1. Execution of try - catch
Whatever the exception reference type (in this case ExceptionA, ExceptionB or Exception) used to refer to the exception object thrown by method runException(), such method will throw objects of type either ExceptionA or ExceptionB. These objects will be assignment compatible with the catch parameters of the first two catch of the main() method.
After paragraphs 8.4.6, 11.2.3 and 14.20.1 of the Java Language Specification, I understood that what we actually specify in a throws clause of a method signature is the list of the exception reference types that will be assignment compatible with any possible exception object thrown from the method (given a class reference type we can make it point to instance objects of itself or to instance objects of its subclasses, not superclasses ). That tells any other caller method what exceptions it may have to deal with when invoking the method with the throws clause. In my code example, the advantage of using the clause throws ExceptionA, ExceptionB is that I will not need to catch java.lang.Exception in the main(). In fact, if I choose clause throws Exception in method runException() and delete the cath(Exception) block from the main() I will get a compile-time error. This is because even if we will be throwing ExceptionA or ExceptionB objects at run-time, the compiler will understand that method runException() may throw out an exception object of type Exception, which will not be assignment compatible with any of the catch parameters in the main() (Exception is a superclass of both ExceptionA and ExceptionB).
It's because, you've been throwing the Subclasses at,
try{
if(what == 'A')
throw new ExceptionA();
else if (what == 'B')
throw new ExceptionB();
}
of "Exception class" which are in turn being thrown out at,
catch(Exception e){
throw e;
}
after being assigned to "Exception class( at Exception e)", it will not make a difference if you specify throwing a Superclass type throws objectReference at
public static void runException(char what) throws Exception){
or Subclass type throws objectReferences at
public static void runException(char what) throws ExceptionA, ExceptionB){
As java compiler allows you to specify a throws ObjectReference, if it is of a Superclass of the object being thrown at the try statement.
These throws declarations are so that you list more explicitly what happens out of the method. Otherwise this is ordinary polymorphism: you use base class to combine in multiple subclasses, however you are definitely not changing the instances, this is why at runtime in both cases the exceptions are resolved to their concrete classes.
As a rule, you should never catch (Exception ex). Because this will catch RuntimeExceptions too. It sometimes makes sense to catch (Throwable t) or to use Thread.setDefaultUncaughtExceptionHandler to customize your uncaught exception handler to catch exceptions and then display them to the user. Sometimes I will catch an Exception, wrap it in a RuntimeException (or an Error) and throw that
When it comes to exceptions, you should really only be catching them when you can do something with them, or when you want to make sure that an exception doesn't cause the rest of the method to not process.
Personally I divide exceptions into 3 types
Problems in your code: This is something for you to fix
Problems with the user: For instance if you tell them to enter a number and they enter 'a', that's the user's error
"Friend" Exceptions: SocketException, for instance, is an example of this. If the socket closes and you have a thread waiting on input on it, it will throw this Exception, releasing the thread and letting you do clean-up on the socket.
Why I need to put the throws clause in the main method to handle the exception? It shouldn't be only the try-catch supposed to handle exceptions? Sorry for my english
public static void main(String[] args) throws IOException {
createFileDude();
}
public static void createFileDude() throws IOException {
File file = new File("C:\\Users\\User\\Desktop\\Test.txt");
try {
System.out.println("Create file>> " + file.createNewFile());
} catch (IOException e) {
e.printStackTrace();
throw e;
}
}
Exception means something went wrong in the 'current method'. Now, the developer can handle it in the catch block of current method, or just tell to the calling method that something went wrong for them to handle.
Like this, eventually the developer can cascade the error back to the operating system. So, it is all about throwing the error back to the calling method or not throwing it back at some point.
In this case, there are two places where you as a developer can decide if the exception message be cascaded back to the OS or not, first is in the method you wrote. As I see you wrote that the exception be thrown, now in main method, you as a developer again have a chance to not throw it to OS (by enclosing in it try-catch but don't throw in catch block), or throw it to OS.
In your example you chose to throw it back to the OS by adding throws clause.
From Java perspective, Java wants the you (the developer) make a conscious decision on any given (checked) exception, and so you'll see compilation errors until you either suppress the exception by not throwing in, or until you actually throw it back to the OS from the 'main' method.
This question already has answers here:
Difference between throw and throws in Java? [duplicate]
(3 answers)
Closed 3 years ago.
I saw a video that explains throws and throw as follows:
Throws - is used to delegate/pass on the exception to the caller method.
class test{
void child() throws filenotfoundException{
//////## this method passes the exception to its caller which is main method
File f = new File("abc")
}
public static void main(String[] args) throws filenotfoundException{
//////##this main method passes the exception to its caller which is JVM
}
}
So in the above example, if file 'abc' doesn't exist, and the exception is not handled using try catch in the child method, the child method will pass on the exception to main method.
As the main method doesn't handle the exceptions using try catch, it also throws or passes the exception to its caller method which is JVM.
Is it correct?
Throw - JVM only understands the logic to pick up predefined exceptions. And hence all the user defined exceptions should manually be created using new Exception and then passed on to JVM using throw keyword.
is it right as well?
The explanation is flawed. First, child() as written isn't going to throw a thing. File not found is not an exception so far and wouldn't be unless you tried to open the file for input.
From your code, though, child() could possibly throw the exception, as could main(). Child doesn't, but it's defined that it might.
Throw is how you actually, well, throw the exception. Like this:
void child() throws FileNotFoundException {
File f("garbage");
if (!f.exists()) {
throw new FileNotFoundException("the world is clean as garbage does not exist");
}
}
Your main() doesn't have a try/catch block, but it could:
void main() {
try {
child();
}
catch (FileNotFoundException e) {
// Oh no!
}
}
throws is used in the method signature to tell everyone that "yes, this method throws an Exception of X type, please be wary" while throw is used to actually launch this Exception and abort the execution of the function.
Yes, depending on the exception, and if you catch it or not, it might bubble all the way up to the JVM. Some Exceptions do not cause the execution to abort however. These are known as RuntimeExceptions. The programmer can decide to handle them, or not, using a try/catch block. RuntimeExceptions do not need to be declared in the function signature.
This question already has answers here:
In Java, is using throws Exception instead of throwing multiple specific exceptions good practice?
(15 answers)
Closed 6 years ago.
Final edit due to this question having been marked as duplicate: this question is about the semantics of the throws declaration - the question which is this said to be a duplicate of handles different aspects of throws and none of those 15 answers there gave me the insight of the chosen answer here. Anyway - so let's keep it here as a duplicate.
In Java you have to declare a throws clause and name the exceptions that this method could throw - so the easy way is to just declare
void myMethod(...) throws Exception
or you could be more specific and for example state
void myMethod(...) throws SQLException, NamingException
in case the method may just throw these two.
I understand that it makes a difference whether in a try/catch block I
try { ... } catch (Exception exc) { ... }
or
try { ... } catch (SQLException | NamingException exc) { ... }
because the first will also catch a RuntimeException, the second won't - so this is a difference.
But is there also any difference in declaring throws Exception vs. throws SQLException, NamingException concerning the semantics of the program? The second may be more readable, but I don't see any other difference. Is there any?
But is there also any difference in declaring throws Exception vs. throws SQLException, NamingException
The difference is:
if you declare throws SQLException, NamingException the compiler assures that you have catched exactly these two exceptions. Otherwise you will get a Unhandled exception type ... error.
On the other hand, if you declare throws Exception, the compiler assures that you have catched Exception.
In the second case, you can still catch any other exception which inherits from Exception without getting a compiler error (like "Exception ... never thrown"). However, you must either catch Exception itself or add the throws Exception to the calling method to allow passing the exception further upwards. For example,
private void someMethod() throws Exception {
throw new NumberFormatException("Illegal number format");
}
If this method gets called, you can catch the NumberFormatException, but you also have to either handle the more generic Exception or declare it in the throws clause (and then handle it further up in the call hierarchy):
public void myMethod() {
try {
someMethod();
}catch(NumberFormatException nfe) {
nfe.printStackTrace();
}catch(Exception ex) {
ex.printStackTrace();
}
}
Or:
public void myMethod() throws Exception {
try {
someMethod();
}catch(NumberFormatException nfe) {
nfe.printStackTrace();
}
}
Yes, there is a difference.
When you use the throws declaration of an exception in a method, you do it so you can handle it later (using try{}catch blocks).
When you handle the exception, you might just do the e.printStackTrace(), but that's not really handling it.
Instead, imagine you want to tell your user "You didn't introduce a number, please correct this mistake" and prompt them to introduce a number. You can do this if you throw NumberFormatException in the method you use to read. But if you throw just Exception, you can't know for sure if that was the error or any other exception, and you might have unexpected behaviours because of that.
The difference between two approach lies based on Exception Handling. For example, if you like to handle all exception in same way then, you should opt for first approach. On the other hand, if you like to deal different exception in different manner, you must go for second approach
I would prefer to mention the exceptions explicitly in the function declaration after the throws keyword because then I know how I should handle these exceptions if they occur in the calling code. See the code below for better understanding..
public static void exceptionExample() throws SQlException, NamingException {
}
public static void main(String[] args) throws SQlException, NamingException {
try {
exceptionExample();
exceptionExample();
}
catch(SQlException e){
System.out.println("Sql exception has occured");
}
catch(NamingException e){
System.out.println("Naming Exception has occured");
}
}
If I would not have mentioned throws SQlException , NamingException explicitly in the function and have used only throws Exception then it implies I do not know which exception may occur. In that case in the catch() {...} block I would have used e.printStackTrace which is not really an efficient method of exception handling because user may never know what happened to the application. But here as you can see that I can inform the user that the respective exception has occurred which makes my application more user friendly.
Also Throwing Exception causes the calling code to catch the exceptions which they may not want to handle depending upon the application and all kinds of reasons.
So I would say it depends upon the wit of the programmer on how he/she wants to handle the exceptions efficiently.....
I am new to Java. And I find it really annoying to keep writing throws IOException in the "main" and all the methods that open a file. For example:
class something{
public static void main(String[] args) throws IOException{
myobj abc = new myobj();
abc.read_file("this_file.txt");
abc.insert("text");
}
}
class myobj{
....
public void read_file(String file_loc) throws IOException{
blablabla
}
}
In this case, I have already written "throws IOException" twice. Is there a way to handle this once and for all ?
Edit:
Thanks for all the good answers. A lot of people suggested using try-catch statements.
I read about try and catch statements and I got really confused. My question is where should I carry on writing my code i.e. abc.insert("text") into the try catch statements after abc.read_file("this_file.txt") ? Should I carry on in catch block or outside it ? This is what really puzzles me.
There's no catch-all "all methods in this class throw this exception," you'll have to declare the exception on each method (e.g., read_file, etc.) or handle it within the method. This is the point of checked exceptions: To ensure that at each stage, it's clear where they may come from and where they're handled.
Note: main shouldn't throw, you should catch the exception and handle it.
Who is main throwing to? No one.
Java has checked and unchecked exceptions. Checked exceptions leave you no choice: you either have to catch them or add them to your method signature in a throws clause.
Unchecked exceptions don't require handling.
You always have the option of catching a checked exception and rethrowing it as a custom unchecked exception.
I'd write it this way:
class something{
public static void main(String[] args)
try {
myobj abc = new myobj();
abc.read_file("this_file.txt");
} catch (IOException e) {
e.printStackTrace();
}
}
}
class myobj{
....
public void read_file(String file_loc) throws IOException{
blablabla
}
}
I am new to Java.
Hi, I hope you enjoy your learning. Learning a new programming language effectively implies learning the idiomatic ways in which to code in that language (even the ones that we subjectively find annoying.)
This is not unique to Java. Whether you do C# or Python or C++ or Haskell, you will be bound to find something that is annoying. Then the question is, what value do you get in the effort to avoid that annoyance.
If you become more productive by avoiding the annoyance, then more power to you. Otherwise, I would follow Maya Angelou's advice: "If you don't like something, change it. If you can't change it, change your attitude."
And I find it really annoying to keep writing
throws IOException in the "main" and all the methods that open a file.
In real life development, you will be handling far more non-main exceptions that main ones (probably only one main.)
So what is the threshold, the ration of main/(all other functions) by which the annoyance is justifiable and constructive? One main and one function? One main and a dozen? One main and a hundred?
Of all the plumbing and elbow grease that needs to be done with Java, declaring exceptions on the main function is an exercise in emotion of very little use.
So take it with a grain of salt, but in my professional opinion (18 years, Java, C++, Python and a lot of other crap) is this: declare your exceptions, even on main.
Why? Because it is possible that other programs might invoke your main. That is, your Java program might be invoked from the console, or it might be embedded (invokable?) from another program.
I've done this a lot for testing or for developing systems that are embeddable. So, in this case,
you want to declare those exceptions. However, since such a program is intended for standalone and embedded use, this is the general pattern I follow (java-like pseudocode, far more simplified than real-life code):
class UtilityDelegate {
UtilitytDelegate(){ .... }
void performWork(File f) throws IOException {
// do something with file
}
}
public class SomeUtility {
public static void main(final String[] args) throws IOException {
File f = null;
try{
// do something that could throw an exception
f = new File(args[0]);
performWork(f);
} finally {
// do necessary clean-up, if any, such as closing file handles,
// sockets, flushing database changes, pray to Lord Xenu, whatever
if( f != null ){
try{
f.close();
}catch (IOException e){
e.printStackTrace(); // or use a logging mechanism or whatever
}
}
}
}
}
Now, your program can be called from the command line:
java SomeUtility myfile
Or from another java class:
public class SomeUtilityClient{
public static void main(final String[] args){
// for brevity, I'm omitting the case when the utility might
// call System.exit() itself.
try{
SomeUtility.main("a-pre-defined-filename");
} catch(IOException e){
someLog("call to utility failed, see exception", e);
System.exit(-1);
}
System.exit(0);
}
}
An argument could be made that such a java client should call the embedded program via another method name, not main. That is fair, and in many cases, it is the better approach.
But just consider this one reason or approach of why to declare your exceptions everywhere, even on your main.
The main method doesn't need to throw anything.
class something{
public static void main(String[] args)
try {
myobj abc = new myobj();
abc.read_file("this_file.txt");
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}
}
I know you may find this language feature annoying but trust me, it is far less frustrating than managing code which does not propagate exceptions. You spend hours and hours wondering why your code is not doing something and then you stumble across this:
try {
doSomethingImportant();
}
catch(Exception e) {
// Nah can't be bothered
}
Simply put, no.
There are two ways to deal with exceptions:
You either handle that exception in your current method (main in your case) by surrounding the API that throws the exception with try-catch and writing code in the catch block to handle it OR
Add "throws IOException" on the method signature in which case you force the callers of your method to deal with it.