I have the simple code below :
class Test {
public static void main(String[] args) {
Test t = new Test();
try {
t.throwAnotherException();
} catch (AnotherException e) {
t.handleException(e);
}
try {
t.throwAnotherException();
} catch (Exception e) {
System.out.println(e.getClass().getName());
t.handleException(e);
}
}
public void throwAnotherException() throws AnotherException {
throw new AnotherException();
}
public void handleException(Exception e) {
System.out.println("Handle Exception");
}
public void handleException(AnotherException e) {
System.out.println("Handle Another Exception");
}
}
class AnotherException extends Exception {
}
Why the method called in the second catch is the one with the signature void handleException(Exception e) whereas the kind of exception is AnotherException?
Overloaded methods are resolved at compile time, based on formal parameter types, not runtime types.
That means that if B extends A, and you have
void thing(A x);
void thing(B x);
then
B b = new B();
thing(b);
will look for a thing() that takes a B, because the formal type of b is B; but
A b = new B();
thing(b);
will look for a thing() that takes an A, because the formal type of b is A, even though its runtime actual type will be B.
In your code, the formal type of e is AnotherException in the first case, but Exception in the second case. The runtime type is AnotherException in each case.
AnotherException extends Exception, which means that anywhere you use "Exception", using an instance of "AnotherException" will qualify.
You should probably read up on Extending Classes for a more detailed explanation of how this works as it's very important in programming.
I guess you wanted to test which Exception is gonna get caught, right?
Then modify your code to throw just one Exception:
try {
t.throwAnotherException();
} catch (AnotherException e) {
t.handleException(e);
}
catch (Exception e) {
System.out.println(e.getClass().getName());
t.handleException(e);
}
which is working as expected.
Exception is the super class so if you write your catch clause with (Exception e) first it will always gets satisfy and get executed.
to improve your code you can modify your code as written below.
class Test {
public static void main(String[] args) {
Test t = new Test();
try {
t.throwAnotherException();
} catch (AnotherException e) {
t.handleException(e);
}
try {
t.throwAnotherException();
}catch (AnotherException e) {
t.handleException(e);
}catch (Exception e) {
System.out.println(e.getClass().getName());
t.handleException(e);
}
}
public void throwAnotherException() throws AnotherException {
throw new AnotherException();
}
public void handleException(Exception e) {
System.out.println("Handle Exception");
}
public void handleException(AnotherException e) {
System.out.println("Handle Another Exception");
}
}
class AnotherException extends Exception {
}
Related
public class Sample {
public static void main(String[] args) {
method();
}
public static void method()
{
try {
System.out.println("function");
throw new StaleElementReferenceException("thih sexception occured");
}
catch (StaleElementReferenceException e) {
method();
}
catch (Exception e) {
System.out.println("AssertFail");
}
}
}
how to avoid Infinite Recursion in a non-return method with Try catch...For Example this code below...when the StaleElementException Occurs only once i want to execute "functions after Exception , if the Stale Element occurs the second time i want it to go to Exception catch and print Assert fail..how?
public class Sample {
public static void main(String[] args) {
method(false);
}
public static void method(boolean calledFromCatchBlock)
{
try {
System.out.println("function");
if(!calledFromCatchBlock) {
throw new StaleElementReferenceException("thih sexception occured");
} else {
throw new Exception();
}
} catch (StaleElementReferenceException e) {
method(true);
} catch (Exception e) {
System.out.println("AssertFail");
}
}
}
You should store somehow the state when you throw an exception (e.g. a boolean flag) outside method(), check this state and throw modified exception next time:
private static boolean alreadyThrown = false;
public static void method()
{
try {
System.out.println("function");
if (alreadyThrown) {
throw new RuntimeException("another exception occured");
} else {
alreadyThrown = true;
throw new StaleElementReferenceException("this exception occured");
}
}
catch (StaleElementReferenceException e) {
method();
}
catch (Exception e) {
System.out.println("AssertFail");
}
}
Or you could provide some argument to the method(int arg) and check its value in a similar way:
public static void main(String[] args) {
method(1);
}
public static void method(int arg)
{
try {
System.out.println("function");
if (arg > 1) {
throw new RuntimeException("another exception occured");
} else {
throw new StaleElementReferenceException("this exception occured");
}
}
catch (StaleElementReferenceException e) {
method(arg + 1);
}
catch (Exception e) {
System.out.println("AssertFail");
}
}
public class TestException extends except2 {
public static void main(String[] args)throws Exception {
try {
try {
throw new TestException();
}
catch (final TestException e){
}
throw new except2();
}
catch (TestException a){
}
catch (Exception e){
throw e;
}
}
public TestException(){
}
}
class except2 extends Exception{
}
Hi all,
my JDK version is 8u45 which is latest one now.
I'm wondering that is "precise rethrow with a final exception" still working in SE 8?
As the code, if I take the "throws Exception" off it'll be compilation error, but it should be able to be ignored according to "precise rethrow with a final exception" function of SE7.
Another question is that we all know if there's an exception happened in the nested try box, we should still throw it out to outer catch box to avoid compilation error, I originally figured that we only need to throw an exception of any types & it'll do, so is my test result, I think it's to let compiler know that there's an exception in try box & catch box got it, too.
but if I alter it like the following code:
public class TestException extends except2 {
public static void main(String[] args)throws Exception {
try {
try {
throw new ArithmeticException();
} catch (final TestException e){
throw e;
}
} catch (TestException a){
} catch (Exception e){
throw e;
}
}
}
the (final TestException e) part will be compilation error with the message:
"the Exception "com.xxx.TestException" is never thrown in the corresponding try block",
and I'm confused because if nested catch block can't handle the exception, it shall goes to outer.
Then if I throw an ArithmeticException in the end of outer try block like this:
try {
try {
throw new TestException();
}
catch (final TestException e){
System.out.println("d");
}
throw new ArithmeticException();
}
catch (TestException a){
}
catch (Exception e){
throw e;
}
Same error to the outer catch box catch (TestException a){}
Why is that?
it should be caught by (Exception e) block.
If I can't throw different types of exception from the first exception of nested try block, why could I throw except2 in the first paragraph of code?
This is Oracles example for the feature, and it still works with Java 8:
static class FirstException extends Exception { }
static class SecondException extends Exception { }
public void rethrowException(String exceptionName)
throws FirstExceptio, SecondException // Since J7 no "Exception" needed
{
try {
if (exceptionName.equals("First")) {
throw new FirstException();
} else {
throw new SecondException();
}
} catch (Exception e) {
throw e; // effective final (i.e. not assigned)
}
}
This is described in the second half of this Oracle document. Your examples are all not really related to it. Especially not the one where you have a more specific and a general catch. This is explicitly mentioned in the document as not working.
Your first block would work if you use except2 (I renamed it to BaseException) which is the more specific one like this:
public class TestException extends BaseException {
public static void main(String[] args) {
try {
try {
throw new TestException();
}
catch (final BaseException e){
throw e; // this is defined as BaseEx, will fail on Java 6
}
}
catch (TestException a){ // this knows that no BaseEx is expected
}
}
public TestException(){
}
}
class BaseException extends Exception { }
As you can see, the main() method does not need to throw Exception anymore since the second catch block was sufficient.
Your first piece of code can be shortened to
class TestException extends except2 throws Exception {
public static void main(String[] args) {
try {
throw new except2(); // this
} catch (TestException a) {
} catch (Exception e) {
throw e;
}
}
public TestException() {
}
}
class except2 extends Exception {
}
You're throwing an except2. A TestException is an except2, but an except2 is not necessarily a TestException. The first catch block cannot handle the except2 exception. So the second one must. Since it further throws that exception, and that exception is necessarily checked, you need to have a throws clause.
Your second piece of code
class TestException extends except2 {
public static void main(String[] args) throws Exception {
try {
try {
throw new ArithmeticException();
} catch (final TestException e) { // nothing above throws a TestException
throw e;
}
} catch (TestException a) {
}
catch (Exception e) {
throw e;
}
}
}
Is trying to catch a TestException in the nested try block. But since TestException is a checked exception, the compiler can and does check if it can be thrown in that block. In your case, it can't. So it complains that's it useless to try and catch it.
Finally, in your last snippet
class TestException extends except2 {
public static void main(String[] args) throws Exception {
try {
try {
throw new TestException();
} catch (final TestException e) {
System.out.println("d");
}
throw new ArithmeticException();
} catch (TestException a) {
} catch (Exception e) {
throw e;
}
}
}
You're throwing and catching a TestException in the nested try-catch statement. So you can reduce the code to
class TestException extends except2 {
public static void main(String[] args) throws Exception {
try {
throw new ArithmeticException();
} catch (TestException a) {
} catch (Exception e) {
throw e;
}
}
}
Which has the same issue as your second piece of code. There is no code path there that can throw a TestException.
Regarding comments, and to simplify the second snippet, the error reduces to
class TestException extends except2 {
public static void main(String[] args) throws Exception {
try {
throw new ArithmeticException();
} catch (final TestException e) { // nothing above throws a TestException
throw e;
}
}
}
You have a catch(TestException) but nothing throws a TestException, so it's useless code which the compiler rejects.
From comments, this is the problem with your cases 2 and 3
// ignore everything around this
try {
// nothing in this block
// can throw a TestException
throw new ArithmeticException();
// this whole catch block is useless code
// Test Exception can never be thrown
} catch (final TestException e){
throw e;
}
// ignore everything around this
when I debug the below code, there is an SmbException and goes catch block line sb.append(pLogger.reportError(pStr, e));, but it does not go into the method reportError().
what is the reason behind this. please advise if any changes.
try {
sfos = new SmbFileOutputStream(sFile);
} catch (SmbException e) {
sb.append(pLogger.rError(pathStr, e));
}
below is rError() method
public String rError(String pxString,Exception e){
String errorToMailStr=null;
abcd="Verifying # "+pxString+"::Error ["+e.getMessage()+"]";
logger.debug("Error when verifying # "+pxString+":Error ["+gMsg(e)+"]");
return abcd;
}
at line logger.debug("Issue "+pxString+":Error ["+gMsg(e)+"]");
is going to below method and ends.
public abstract class ReflectiveCallable {
public Object run() throws Throwable {
try {
return runReflectiveCall();
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
Based on what you have revealed here, there is a problem in getExceptionMsg()
I'm working on some server-side code that wraps all exceptions before passing them to the client side, due to this all client facing methods have the following code
try{
DoSomething();
} catch (ExceptionA e) {
throw new CustomException(AType, e);
} catch (ExceptionB e) {
throw new CustomException(BType, e);
} catch (Exception e) {
throw new CustomException(Unexpected, e);
}
to have this repeated in every method seems to violate the DRY principle and I was wondering what the best way to refactor it would be. For instance I was thinking a wrapper method such as:
private void wrapException(Exception e) {
if (e instanceof ExceptionA) {
throw new CustomException(AType, e);
}
etc...
Take a look at AspectJ soften exception.
Also look at Guava's Throwables.
There is also Lamboks sneaky exception.
The other option is to use Anonymous object instances aka closures.
public abstract class Wrapper {
public void execute() {
try {
// do some boiler plate before
this.wrap();
// do some boiler plate after.
} catch (ExceptionA | ExceptionB ex) {
Type t = determineType(ex);
throw new CustomException(t, ex);
}
}
public void abstract wrap();
}
Now in your code you do something like:
new Wrapper() {
public void wrap() {
DoSomething();
}
}.execute()
This is possible in Java7 and up:
http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html
Copy-paste example from above doc:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
This is one way to go about it:
Exception caughtEx = null;
String extraInfo = null;
try{
DoSomething();
} catch (ExceptionA e) {
caughtEx = e;
extraInfo = AType;
} catch (ExceptionB e) {
caughtEx = e;
extraInfo = BType;
} catch (Exception e) { // catching Exception is usually a bad idea, just let it bubble up without catching...
caughtEx = e;
extraInfo = Unexpected;
}
if (caughtEx != null) throw new CustomException(extraInfo, caughtEx);
public class Test {
public static void main(String[] args) {
try {
doSomething(new TestCallback() {
#Override
public void doCallback() {
throw new NullPointerException();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public static void doSomething(TestCallback callback){
callback.doCallback();
}
interface TestCallback {
public void doCallback();
}
}
RESULT:
java.lang.NullPointerException
at managers.concurrency.Test$1.doCallback(Test.java:11)
at managers.concurrency.Test.doSomething(Test.java:20)
at managers.concurrency.Test.main(Test.java:8)
In the above code we will get NullPointerException because the callback code is executed in the different part of stack. Is there a way to catch the such exceptions locally?
You are already catching the exception. Try something as follows -
try {
doSomething(new TestCallback() {
#Override
public void doCallback() {
throw new NullPointerException();
}
});
} catch (Exception e) {
System.out.println("Exception caught !!!");
}
Output:
Exception caught !!!