What does the `throws IOExeption` do? [duplicate] - java

This question already has answers here:
What does "Throws" do and how is it helpful? [duplicate]
(5 answers)
Closed 7 years ago.
What does the throws IOExeption actually do when importing a file?
Example
public static void main(String args[]) throws IOException {
Scanner scanner = new Scanner(new File("C:\\Location"));
// more code
scanner.close();
}

throws indicates that a method requires a caller to either handle the exception, or allow the exception to continue being thrown up the call stack. The former requires the method that can throw the exception to be called in a try-catch block; the latter requires the calling method to include the type of exception (e.g. IOException) in its own method signature.
In your case, main(String[] args) includes the exception in its signature, meaning it does not plan on handling the exception but instead will pass it up the stack. Since main is the program's entry point, there is nothing else to handle the exception and the program would terminate.

In Java, the IO classes throws a checked exception called IOException, e.g. saying "File not found". A checked exception must be handled in a try-catch block or it must be allowed to bubble up to the caller of your method by declaring that your method may cause that exception to be raised.
In your book, there's no need to handle exceptions, so simply allowing the exception to bubble up is the easiest to do. You'll learn more about this later.

The throws IOExeption actually does not do anything when "importing" the file. Rather, it is relevant to what happens when you fail to "import" the file.
The Scanner class throws an IOException when the file could not be read for some reason. However, IOException is a checked exception. This means that Java demands that you handle the exception somehow in a try/catch block.
When you declare throws IOException, you are telling Java that you will not handle the exception, and instead allow it to bubble up, and leave the caller of your method to handle the exception instead.
In this particular case, you are already in the main method. So you will get a stack trace should be exception be thrown.

When you are stating that a method throws an exception you are actually saying that the code that is outside (the caller or his ancestors in the callstack) this method is the one that's gonna need to catch the exception (and maybe no one)
also, in your method, youre gonna need to use "throw" key word.
for example, a case when the calling code IS catching the thrown execption:
class example
{
static void method() throws IOExeption
{
// in this code section you use the Scanner and from inside its code an
// an IOExeption is thrown ( using "throw IOExecption;")
}
public static void main(String args[])
{
try
{
method();
}
catch (IOExeption ioe)
{
// handle it however you want
}
}
}

Related

What does "error: unreported exception <XXX>; must be caught or declared to be thrown" mean and how do I fix it?

New Java programmers frequently encounter errors phrased like this:
"error: unreported exception <XXX>; must be caught or declared to be thrown"
where XXX is the name of some exception class.
Please explain:
What the compilation error message is saying,
the Java concepts behind this error, and
how to fix it.
First things first. This a compilation error not a exception. You should see it at compile time.
If you see it in a runtime exception message, that's probably because you are running some code with compilation errors in it. Go back and fix the compilation errors. Then find and set the setting in your IDE that prevents it generating ".class" files for source code with compilation errors. (Save yourself future pain.)
The short answer to the question is:
The error message is saying that the statement with this error is throwing (or propagating) a checked exception, and the exception (the XXX) is not being dealt with properly.
The solution is to deal with the exception by either:
catching and handling it with a try ... catch statement, or
declaring that the enclosing method or constructor throws it1.
1 - There are some edge-cases where you can't do that. Read the rest of the answer!
Checked versus unchecked exceptions
In Java, exceptions are represented by classes that descend from the java.lang.Throwable class. Exceptions are divided into two categories:
Checked exceptions are Throwable, and Exception and its subclasses, apart from RuntimeException and its subclasses.
Unchecked exceptions are all other exceptions; i.e. Error and its subclasses, and RuntimeException and its subclasses.
(In the above, "subclasses" includes by direct and indirect subclasses.)
The distinction between checked and unchecked exceptions is that checked exceptions must be "dealt with" within the enclosing method or constructor that they occur, but unchecked exceptions need not be dealt with.
(Q: How do you know if an exception is checked or not? A: Find the javadoc for the exception's class, and look at its parent classes.)
How do you deal with a (checked) exception
From the Java language perspective, there are two ways to deal with an exception that will "satisfy" the compiler:
You can catch the exception in a try ... catch statement. For example:
public void doThings() {
try {
// do some things
if (someFlag) {
throw new IOException("cannot read something");
}
// do more things
} catch (IOException ex) {
// deal with it <<<=== HERE
}
}
In the above, we put the statement that throws the (checked) IOException in the body of the try. Then we wrote a catch clause to catch the exception. (We could catch a superclass of IOException ... but in this case that would be Exception and catching Exception is a bad idea.)
You can declare that the enclosing method or constructor throws the exception
public void doThings() throws IOException {
// do some things
if (someFlag) {
throw new IOException("cannot read something");
}
// do more things
}
In the above we have declared that doThings() throws IOException. That means that any code that calls the doThings() method has to deal with the exception. In short, we are passing the problem of dealing with the exception to the caller.
Which of these things is the correct thing to do?
It depends on the context. However, a general principle is that you should deal with exceptions at a level in the code where you are able to deal with them appropriately. And that in turn depends on what the exception handling code is going to do (at HERE). Can it recover? Can it abandon the current request? Should it halt the application?
Solving the problem
To recap. The compilation error means that:
your code has thrown a checked exception, or called some method or constructor that throws the checked exception, and
it has not dealt with the exception by catching it or by declaring it as required by the Java language.
Your solution process should be:
Understand what the exception means, and why it could be thrown.
Based on 1, decide on the correct way to deal with it.
Based on 2, make the relevant changes to your code.
Example: throwing and catching in the same method
Consider the following example from this Q&A
public class Main {
static void t() throws IllegalAccessException {
try {
throw new IllegalAccessException("demo");
} catch (IllegalAccessException e){
System.out.println(e);
}
}
public static void main(String[] args){
t();
System.out.println("hello");
}
}
If you have been following what we have said so far, you will realise that the t() will give the "unreported exception" compilation error. In this case, the mistake is that t has been declared as throws IllegalAccessException. In fact the exception does not propagate, because it has been caught within the method that threw it.
The fix in this example will be to remove the throws IllegalAccessException.
The mini-lesson here is that throws IllegalAccessException is the method saying that the caller should expect the exception to propagate. It doesn't actually mean that it will propagate. And the flip-side is that if you don't expect the exception to propagate (e.g. because it wasn't thrown, or because it was caught and not rethrown) then the method's signature shouldn't say it is thrown!
Bad practice with exceptions
There are a couple of things that you should avoid doing:
Don't catch Exception (or Throwable) as a short cut for catching a list of exceptions. If you do that, you are liable catch things that you don't expect (like an unchecked NullPointerException) and then attempt to recover when you shouldn't.
Don't declare a method as throws Exception. That forces the called to deal with (potentially) any checked exception ... which is a nightmare.
Don't squash exceptions. For example
try {
...
} catch (NullPointerException ex) {
// It never happens ... ignoring this
}
If you squash exceptions, you are liable to make the runtime errors that triggered them much harder to diagnose. You are destroying the evidence.
Note: just believing that the exception never happens (per the comment) doesn't necessarily make it a fact.
Edge case: static initializers
There some situations where dealing with checked exceptions is a problem. One particular case is checked exceptions in static initializers. For example:
private static final FileInputStream input = new FileInputStream("foo.txt");
The FileInputStream is declared as throws FileNotFoundException ... which is a checked exception. But since the above is a field declaration, the syntax of the Java language, won't let us put the declaration inside a try ... catch. And there is no appropriate (enclosing) method or constructor ... because this code is run when the class is initialized.
One solution is to use a static block; for example:
private static final FileInputStream input;
static {
FileInputStream temp = null;
try {
temp = new FileInputStream("foo.txt");
} catch (FileNotFoundException ex) {
// log the error rather than squashing it
}
input = temp; // Note that we need a single point of assignment to 'input'
}
(There are better ways to handle the above scenario in practical code, but that's not the point of this example.)
Edge case: static blocks
As noted above, you can catch exceptions in static blocks. But what we didn't mention is that you must catch checked exceptions within the block. There is no enclosing context for a static block where checked exceptions could be caught.
Edge case: lambdas
A lambda expression (typically) should not throw an unchecked exception. This is not a restriction on lambdas per se. Rather it is a consequence of the function interface that is used for the argument where you are supplying the argument. Unless the function declares a checked exception, the lambda cannot throw one. For example:
List<Path> paths = ...
try {
paths.forEach(p -> Files.delete(p));
} catch (IOException ex) {
// log it ...
}
Even though we appear to have caught IOException, the compiler will complain that:
there is an uncaught exception in the lambda, AND
the catch is catching an exception that is never thrown!
In fact, the exception needs to be caught in the lambda itself:
List<Path> paths = ...
paths.forEach(p -> {
try {
Files.delete(p);
} catch (IOException ex) {
// log it ...
}
}
);
(The astute reader will notice that the two versions behave differently in the case that a delete throws an exception ...)
More Information
The Oracle Java Tutorial:
The catch or specify requirement
... also covers checked vs unchecked exceptions.
Catching and handling exceptions
Specifying the exceptions thrown by a method

SonarQube error: Refactor this method to throw at most one checked exception

I am using SonarQube and it shows the following error:
Public methods should throw at most one checked exception.
// Noncompliant
public void delete() throws IOException, SQLException { /* ... */ }
// Compliant
public void delete() throws SomeApplicationLevelException { /* ... */ }
Does this means, SomeApplicationLevelException is a parent class and IOException and SQALException are derived from it? And we should throw the parent class exception? Thereby adhering to method throwing only 1 checked exception?
Because I have 2 exceptions that i have defined say for example Exception1 and Exception2 that extend Exception. And my method say, sampleMethod() throws them i.e,
public void sampleMethod() throws Exception1, Exception2 {
}
And the error is shown here. So should I have one class as parent (say MainException) and derive Exception1 and Exception2 from it and throw parent exception class? Like below:
public void sampleMethod() throws MainException {
}
Is the above solution proper?
If you have a method in your application that is declared as throws SQLException, IOException, you are probably leaking internal implementation details to your method's users. Specifically, you're saying:
Your method is implemented using JDBC and file I/O. Your users don't care how your method is implemented; they only care about what your method does.
Your method, including any future version of it, will never throw any other checked exception. If in future you change your method so that it might throw another checked exception, it will break backwards compatibility.
The advice is to create your own application-specific class (derived from Exception), and only throw that in your method. You can, if you like, wrap the SQLException or the IOException (or any other exception) inside your application-specific exception as the cause.
Note, however, that there is a school of thought that says Java checked exceptions are a bad idea (and one of the reasons C#, and more modern languages such as Kotlin, don't have checked exceptions).
UPDATE: the above answer related to the first version of the question (edit #1). The question was subsequently updated to point out that the two thrown exceptions were application-defined ones, so therefore much of the above rationale no longer applies. The answer to the updated question is explained in this post.
IOexception and sqlexception both are checked exception s,totally different from each other , now if we extend both from one exception and throw the parent exception , which is not a mandatory in java, it will be kind of misguiding the user of the api.
However, if you want to do it in ur app to avoid sonarqube error , you can catch all your specific exceptions and throw a custom exception wrapping the original exception information in exception message.
for example
try{
///piece of code that throws IOException and SQLException
}catch(IOException | SQLException ex){
throw new DataException(ex,"Any customized message you want");
}
This DataException will then will be included in the throws clause of method signature having this try catch.
DataException extends Exception class and by passing ex in the contructor you are wrapping the original exception in custom exception with your original exception info preserved.

Is disabling Checked Exceptions in Java possible?

I was reading an article about checked and unchecked Exceptions in Java and found this article/link:
https://projectlombok.org/disableCheckedExceptions.html
According to the article it's just a hack developed for javac.
Consider the code snippet below:
import java.io.*;
class Example
{
public static void main(String args[]) throws IOException
{
FileInputStream fis = null;
fis = new FileInputStream("myfile.txt");
int k;
while(( k = fis.read() ) != -1)
{
System.out.print((char)k);
}
fis.close();
}
}
Here I have to write public static void main(String args[]) throws IOException
because I am trying to open a file. Here "throws" clause is a must. Without it I will get an error. What if I am sure about the Existance of the file I am opening. i.e.myfile.txt in the mentioned location. At some point one can feel that few Checked Exceptions are not required for the code.
Is there any facility provided by Java to disable checked Exceptions according to the need?
Even after doing so much research I could not find a proper answer for it.
Is there any facility provided by Java to disable checked Exceptions according to the need?
No official facilities, but there are workarounds one can use when needed:
First, since there are both checked and unchecked exceptions in java, using unchecked exceptions might be an option. All exceptions which derive from RuntimeException are unchecked:
RuntimeException is the superclass of those
exceptions that can be thrown during the normal operation of the
Java Virtual Machine.
A method is not required to declare in its throws
clause any subclasses of RuntimeException that might
be thrown during the execution of the method but not caught.
Interesting read here, here.
Then there is type erasure which allows to throw a checked exception without declaring it.
This is what project lombok uses for #SneakyThrows
import lombok.SneakyThrows;
public class SneakyThrowsExample implements Runnable {
#SneakyThrows(UnsupportedEncodingException.class)
public String utf8ToString(byte[] bytes) {
return new String(bytes, "UTF-8");
}
#SneakyThrows
public void run() {
throw new Throwable();
}
}
Use with caution:
Be aware that it is impossible to catch sneakily thrown checked types directly, as javac will not let you write a catch block for an exception type that no method call in the try body declares as thrown.
And lastly it's only the compiler which cares about checked exceptions, it's not part of the jvm at all. Once you're past the compiler stage anything is possible. So writing bytecode directly or using a version of javac with checked exceptions disabled completely bypasses them.
Other than hacking the compiler there is no option to disable checked exceptions I know of. Best you can do is catch the checked exception and rethrow it within a runtime exception if you don't want to force the client code to handle the checked exception.

Getting error while using a throws clause with an overriding method in java? [duplicate]

This question already has answers here:
What are reasons for Exceptions not to be compatible with throws clauses?
(4 answers)
Closed 4 years ago.
I am getting a error when i am using a throw clause with the method demo().And i want to know that what are the limitations of using throws in inheritance.
The error is: Exception ClassNotFoundException is not compatible with throws clause in Test.demo().
Class Test
{
public void demo() throws NumberFormatException, ArrayIndexOutOfBoundsException//error
{
//something here
}
public void demo(String s)
{
//something here
}
}//end of Test class
public class MyTest extends Test
{
public void demo() throws IndexOutOfBoundsException,ClassNotFoundException
{
//something here
}
public static void main(String[] args)
{
}
}
ClassNotFoundException is a checked exception - and you can't declare that a method override will throw any checked exceptions that the method it's overriding doesn't declare.
From section 8.4.8.3 of the JLS:
A method that overrides or hides another method, including methods that implement abstract methods defined in interfaces, may not be declared to throw more checked exceptions than the overridden or hidden method.
Consider, for example:
Test t = new MyTest();
t.demo();
There's nothing in that code to indicate that ClassNotFoundException will be thrown, because Test.demo() doesn't declare that it will be thrown. However, the whole point of checked exceptions is that the caller is forced to consider what to do with them (catch them or declare that they might throw the exception too). The ability to override a method and declare that it throws a new checked exception not covered by the original method declaration would make a nonsense of that.
It raises the compiler error because you break one of the core principles of inheritance in Java (and in OOP proper). This principle is the overriding member cannot impose more restrictions to the caller than the overridden member, as declared in the super class, even if we discuss about access type or declared exception types.
In your case, ClassNotFoundException is not declared in the super class, nor any of its ancestors.
When you override a method in child class then the throws clause must be compatible with the overridden method. In your case your Test.demo() method throws NumberFormatException, ArrayIndexOutOfBoundsException which are not mandatory for the throws clause because they are RuntimeExceptions
In your MyTest.demo() method you are throwing IndexOutOfBoundsException,ClassNotFoundException out of which IndexOutOfBoundsException is a RuntimeException and that is again not mandatory to throw. ClasssNotFoundException is a checked exception and there is nothing in your parent class demo() method that could match it. hence the error you are getting.
Two options to correct:
add ClassNotFoundException to your Test.demo()
remove it from MyTest.demo()
Hope this helps

Correctly setting up Java exception handling

I've been attempting to write Java exception handlers for a while now, have tried multiple methods and have even visited/read through Oracle's "The Java Tutorials" and I still cannot get it straight. I'm unsure what I am doing wrong. I have a given class (TooLowException) for the exception that I am trying to use. In the method I am attempting to use it in I am using an argument that I need to catch if it is less than zero.
public int func(int num) throws TooLowException {
int blah = num + 1;
if ( blah < 0) {
return blah;
}
else {
String error = "Input is too low.";
throw new TooLowException(error);
}
}
This is the exception class:
public class TooLowException extends Exception {
public TooLowException(String response) {
super(response);
}
}
I'm getting the error in Oracle "Unhandled Exception type TooLowException". I've also attempted the try-catch method as well, but it also doesn't work for me. Hopefully this is enough information for someone to point out what I'm doing incorrectly. I need to be set right in my ways of exception handling.
Taken from what info you've given, it seems that you need to have a try/catch block somewhere in your code. Basically somewhere in your application that func(int) method is being called, or needs to be called if you're running into a compiler error telling you the "Unhandled Exception type TooLowException." General rule for exceptions is Handle/Catch or Declare. This can be broken down like this:
Handle/Catch: If you choose to handle the exception, then the "throws" declaration should be removed from the method signature ("public int func(int num) throws TooLowException" becomes "public int func(int num)"). The idea behind this approach is that you as the programmer intend to handle this type of exception because it's specific enough to the method that you don't want external code to have to worry about handling the exception outside of the scope of the method. This requires that you "handle" the exception yourself, by using a try/catch block.
Declare: This is the method you went with. You are stating that whatever class uses this function has the burden of handling the exception with the try/catch block. This would be used if the method you wrote is generic enough that many different applications can use it and that handling the exception should be application specific, i.e., it's up to other developers to handle it in their own way. Some people like to just log things, others like to have a different control flow execute upon receiving certain exceptions.
Here's what works, sorry if it basically answers an exercise you needed to do, but it's in the interest of helping you! Please take time to understand what is happening here:
public class YourClassThisStuffIsIn {
public static int func(int num) throws TooLowException {
int blah = num + 1;
if ( blah < 0) {
return blah;
}
else {
String error = "Input is too low.";
throw new Exception(error);
}
}
public static void main(String[] commandlineArgument){
try {
YourClassThisStuffIsIn.func(3);
} catch (TooLowException tle){
System.out.println("Caught " + e);
}
}
}
When you click run in your IDE, or you run through the console, the JVM looks for the main method with the correct signature. In this case it finds it, and it executes the main method. First line is a try, meaning the JVM has to prepare itself for the possibility of a problem in the application, allowing it to recover in case an exception is thrown. In this case, the only exception that can be thrown is a TooLowException, which you have written how to handle it inside the catch block. Your way of handling it is simply printing the stack trace out, which is fine I think in this situation.
I've changed your example slightly, making your method static just so it's quicker to write. I also suspect that the intent is that the commandLineArgument is meant to be the number passed into the func(int) method, so in that case you're looking at the func method to look like func(Integer.parseInt(commandlineArgument[0])).
Bonus points for you is noticing that parseInt throws a NumberFormatException too, but you will of course remember that java.lang.RuntimeException and its subclasses aren't checked exceptions so there is no requirement to catch them, though it is good practice!

Categories