Catching multiple exceptions in Java-8 - java

While trying out the multi-catch feature I found in my m1() method everything is working fine as expected.
However, in m2() the same code does not compile. I have just changed the syntax to reduce the number of lines of code.
public class Main {
public int m1(boolean bool) {
try {
if (bool) {
throw new Excep1();
}
throw new Excep2();
//This m1() is compiling abs fine.
} catch (Excep1 | Excep2 e) {
return 0;
}
}
public int m2(boolean b) {
try {
throw b ? new Excep1() : new Excep2();
//This one is not compiling.
} catch (Excep1 | Excep2 e) {
return 0;
}
}
private static interface I {
}
private static class Excep1 extends Exception implements I {
}
private static class Excep2 extends Exception implements I {
}
}
Why doesn't method m2() compile?

The type of the expression
b ? new Excep1() : new Excep2()
is Exception, since that's the common supertype of Excep1 and Excep2.
However, you are not catching Exception, so the compiler complains about it.
If you catch Exception, it will pass compilation:
public int m2(boolean b) {
try {
throw b ? new Excep1() : new Excep2();
} catch (Exception e) {
return 0;
}
}
I tried to find the JLS entry that explains the type of conditional ternary expression in your example.
All I could find was that this particular expression is a 15.25.3. Reference Conditional Expression.
I'm not entirely sure if it counts as a poly expression or a standalone expression. I think it's standalone (since poly expressions involve an assignment context or an invocation context, and I don't think a throw statement counts as either of those).
For a standalone expression: "If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression."
In your case, the second and third operands have three common types - Object, Throwable and Exception - the type of the expression must be one of the latter two, since, "The Expression in a throw statement must either denote a variable or value of a reference type which is assignable (§5.2) to the type Throwable."
It appears that the compiler picks the most specific common type (Exception), and therefore a catch (Exception e) solves the compilation error.
I also tried to replace your two custom exceptions with two sub-classes of IOException, in which case catch (IOException e) solves the compilation error.

You're confusing the compiler with this line:
throw b ? new Excep1() : new Excep2();
The compiler sees that the result of the expression (to the right of the throw) is the common super class between Except1 and Except2, which is Exception, and therefore the effective type you are throwing becomes Exception. The catch statement cannot pick up that you're trying to throw Excep1 or Except2.

Java restrict you to catch or declare all exception types that method can throws,
It search for common parent for both (/all) Exceptions and expect you to catch or declare as throws, for example if Excep1 extends Throwable you will have to catch also Throwable
In first case Java is sure you are either throwing Excep1 or Excep2

Related

Is there a short elegant way to write variable providing with exception?

So, I want to write these kind of things for my code, but there's too much code for one variable. How can I use modern Java for solving this problem shorter or cleaner? Moving it in the separate method doesn't solve the problem, because I still need to check the variable for null, which is wordy and adds extra method that used only once. It is possible to use Optionals here? Seems like return prevents this. Maybe there's the way for collapsing this thing into one for many variables like the foo described below? I don't know, just something to make it more readable and clean.
Foo foo;
try {
foo = FooProvider.getFoo(...);
} catch (FooProvidingException e) {
System.err.println("Foo exception: " + e.getMessage());
return;
}
// use foo, maybe in another method (when foo is the field).
I know, this question may be opinionated, but any help would be a valid answer.
Sorry for my poor english and thanks in advance!
What you're asking is not very clear, so I don't know at which extent my answer will be meaningful.
If I understand well, you have fields of any type (Foo, Bar...) and you would like to instantiate them using whatever kind of provider you wish, which can throw an exception while providing.
So at first, I don't think that you should return if an exception is thrown by the provider, but rather re-throw it or handle it. Because if you had an exception while getting your Foo and so you actually don't have a Foo, why would you continue (or why wouldn't you try to handle it somehow)?
Now this said and assuming that re-throwing/handling is taken care of, then I would define a ThrowingSupplier functional interface:
#FunctionalInterface
public interface ThrowingSupplier<T, E extends Exception> {
T get() throws E;
}
... and then I would create a static method like this:
public static <T, E extends Exception> T provide(ThrowingSupplier<T, E> supplier) {
try {
return supplier.get();
} catch (Exception e) {
System.err.println("Exception: " + e.getMessage());
throw (E) e;
}
}
So at that point, I would be simply calling this utility method every time that I want to execute such kind of operation:
Foo foo = provide(() -> FooProvider.getFoo(...)); //either creates a Foo, or prints and re-throw a FooProvidingException
Bar bar = provide(() -> BarProvider.getBar(...)); //either createa a Bar, or prints and re-throw a BarProvidingException
Integer myInt = provide(() -> 3);
String myStr = provide(() -> "hello");
//... and so on
But of course, at least once you'll have to extract the logic. Then it's all about extracting it in a way that it becomes generic and doesn't need to be repeated for each distinct type of object.
I am also not sure what the end-goal here is but, as I understand it, here's a simpler version of achieving the following:
Declaring and initializing the variable(s)
Fetching values for it with a service provider
Handling any exceptions thrown by this (or if the value is null) and exiting method
Continuing execution if everything is as expected
public static void main(String[] args) {
Foo foo1, foo2, foo3, foo4;
try {
foo1 = Optional.ofNullable(FooProvider.getFoo()).orElseThrow(new FooProviderException(1));
foo2 = Optional.ofNullable(FooProvider.getFoo()).orElseThrow(new FooProviderException(2));
foo3 = Optional.ofNullable(FooProvider.getFoo()).orElseThrow(new FooProviderException(3));
foo4 = Optional.ofNullable(FooProvider.getFoo()).orElseThrow(new FooProviderException(4));
// this works in or out of try/catch block
foo1.printName();
foo2.printName();
foo3.printName();
foo4.printName();
} catch (FooProviderException fpe) {
System.out.println("Exception: " + fpe);
return;
}
// this works in or out of try/catch block
foo1.printAgain();
foo2.printAgain();
foo3.printAgain();
foo4.printAgain();
}

Why doesn't instanceof narrow multicatch union types

The sample function catches checked Exceptions A and B and throws A.
I expected the if statement with instanceof to unwind the union to the expected type, however I still need to cast it.
Is there a reason Java's type system can't/doesn't unwind the union type with instanceof?
public static void throwsA() throws ExceptionA {
try {
funThatThrowsAorB();
} catch (ExceptionA | ExceptionB e) {
// common code
if (e instanceof ExceptionA) {
throw e; // unhandled exception error
throw (ExceptionA)e; // no problem
} else {
throw new ExceptionA(e);
}
}
}
The Java language never narrows a type when entering an if-statement (or any other conditional).
However, Java 14 introduced pattern matching for instanceof expressions as a preview feature:
if (obj instanceof String s) {
// can use s here
} else {
// can't use s here
}
As you can see, this introduces a new variable with the narrowed type, rather than narrowing the type of the existing variable. I am not certain why they chose that route, but I suspect backwards compatibility played a role. Specifically, if you simply narrow the type of an existing variable when entering a conditional, it might break existing code such as the following program:
Number number = 42;
if (number instanceof Integer) {
number = 0.01 * number;
}
To fix that, you'd need to change the type of the variable not just when entering a conditional, but on any assignment. That's more complicated, but TypeScript shows that this is possible:
let x: number | string = "23";
if (typeof x === "string") {
x.charAt(0); // x is a string here
x = 3;
x.toPrecision(2); // but a number here
}
I don't know why the Java design team disliked the TypeScript approach.
Because when you are inside of the catch block, e is an instance of a capture type for both exceptions A and B. By casting, you are specifying that you are throwing ExceptionA specifically:
//e is an "instanceof" either ExceptionA or ExceptionB, but not specified yet!
//For now, e is simply the most specific shared parent type (Exception I assume)
ExceptionA eA; //Cannot be set to e! Cannot coerce Exception into ExceptionA
if (e instanceof ExceptionA) {
eA = (ExceptionA) e; //Have to explicitly cast
throw eA;
}
This works, because your method is specified to be capable of only throwing ExceptionA:
public static void throwsA() throws ExceptionA { ...
As far as why this is required, the error message from attempting an assignment is also pretty clear:
#Andreas offers a much more clear solution, which is just directly handling these errors individually:
try {
//A or B exceptional code
} catch (ExceptionA eA) {
throw eA;
} catch (ExceptionB eB) {
//... B handling
}

Java check instance of an object when it's obj is unknown

I'm new to Java with a decent background in python. I'm looking for a magic sauce in Java which is equivalent to isinstance() in python. I know we can do something like
if (cls.isInstance(obj)){ ... }
But I don't even know which cls it would be so I need something to tell me what instance is obj is. I can't check for hundreds of classes.
Thank you in advance.
EDIT:
I'm dealing with some exception which is wrapped in few other custom exceptions. My primary goal was to catch the exception for which I need to know what instance it is.
Exceptions have inheritance too. That means you don't have to know its exact class to catch it.
So if you want to catch every exception, you do
try {
// the code that throws the exception
} catch (Exception e) {
// handling the exception
}
If you are really desparate you can replace the Exception above with Throwable, to catch even more stuff, but in most cases, that would be a bad idea.
you can check the class instance by instanceof keyword in java. It returns true or false.
MyClass obj = new MyClass();
if(obj instanceof MyClass) {
//Do what you want
}
If you want to check exceptions which exception it is then in java every Exception is child of Exception class. you will check for any number of classes in which exception may be wrapped. at the end you will catch in Exception type. Now every exception will be catch.
try{
} catch(CustommException1 e) {
} catch(CustomException2 e) {
} catch(Exception e) {
}
You can get the full name of the class of obj by using
obj.getClass().getName()
If you don't like package names, you can also do
obj.getClass().getSimpleName()
Try instanceof operator...
for example:
` class Simple1{
public static void main(String args[]){
Simple1 s=new Simple1();
System.out.println(s instanceof Simple1);//true
}
} `
There is no way to get a specific custom class by using instanceof or .getClass() in an Object. It would give you a type of LinkedHashMap.
To know the specific instance of the Object, the only way is checking its Keys, or trying to cast it.
There isn't a "magic sauce" that gives you what type of a custom class is an Object.

Catch exception from toString method in Java

Recently I saw following piece of code on GitHub:
private static String safeToString(Object obj) {
if (obj == null) return null;
try {
return obj.toString();
} catch (Throwable t) {
return "Error occured";
}
}
I've never placed toString() method invocations inside the try-catch blocks. But now when I think about it, it might make sense. For example someone could overwrite toString() method in it's class that might throw a runtime exception, like NullPointerException. So we can try to catch Exception. But why Throwable? Do you think it makes any sense?
There is almost never a good reason to do this. The contract of toString() does not say it’s permissible to throw an exception from that method. Any code which throws an exception is broken code, and such an exception needs to be exposed and fixed, not suppressed.
In the case where you are converting some “bad” object from a library which is out of your control to a String, it might be appropriate to write catch (RuntimeExcepton e), but such a catch should be accompanied by comments which describe in detail why it is necessary, because under normal circumstances, it is not needed.
Rogue exception-throwing toString methods aside, note that Java already has at least two “safe” ways to convert a possibly null value to a String:
Objects.toString(obj, null)
String.valueOf(obj)
…so I would question whether the safeToString method should exist at all.
There are rare cases where you might want to catch an Error like this. In general it's a bad idea however, in this case it might make sense as this is generally for logging/debugging purposes and not used directly by the application.
I would prefer something more informative such as
private static String safeToString(Object obj) {
if (obj == null) return null;
try {
return obj.toString();
} catch (Throwable t) {
return obj.getClass() + ".toString() threw " + t;
}
}
e.g.
class Element {
Object data;
Element e;
public String toString() {
return data + (e == null ? "" : e.toString());
}
}
Element e = new Element();
e.data = "hi";
e.e = e; // oops
System.out.println("e: " + safeToString(e)); // doesn't kill the thread or JVM.
Throwable is the parent class of Exception and Error.
It is normally a bad idea to try and catch Error, as it is designed to not be caught.
Catching Throwable is just the overachieved and counterproductive version of catching Exception. Nonetheless, if for some reason you created another kind of Throwable you want to catch along with an Exception, that could be a way to do that in a single try/catch block. Not that it would be a clean way to do so, but it would work.
EDIT for the TL;DR : in most cases, catch Exception instead of Throwable.
It is incorrect to catch any Throwable and then continue execution since it includes Error, which is meant to be fatal:
From the Javadocs:
An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it.
That is, some Errors can be recovered (e.g. LinkageError), but others not so much.
But catching Exception might be a valid use-case for example in logging code where you don't want the execution to break simply because a call to toString() fails:
private static String safeToString(Object obj) {
try {
return obj == null ? "null" : obj.toString();
} catch (Exception e) {
return "<exception: " + e + ">";
}
}

Java: Wrap code with a try catch block function?

I have several functions where I am casting an object to an explicit type.
The problem is, when this object is created, the type may not match the type I am casting to. Somewhere along the line there are some conversions that take place. However, it is possible the code never reaches these conversions. The fact that it doesn't is not an issue.
So when the code reaches the point where the casting will occur, all I need to do is put the part into a try catch block. In fact I don't even need to handle the exception in any special way.
But I have a lot of these functions. I would like to know if there is some way to wrap lines of code with a try catch block without actually writing out the try catch block. If I can call some function some how that will do it automatically.
try
{
// cast something
}
catch( ClassCastException e )
{
}
Instead I want to call a method that will put the try catch block around // cast something. Is there any way to do something like this?
Note: I don't do anything when I catch the ClassCastException. It is okay if I can't cast the object correctly, but I need to catch the exception so the code execution won't jump to some other place.
You can write a method like this to do the casting for you while ignoring any ClassCastException.
public static <I, O> O cast(I input, Class<O> outClass) {
try {
return outClass.cast(input);
} catch (ClassCastException e) {
return null;
}
}
You can use it like this:
Number n = new Integer(1);
Integer i = cast(n, Integer.class);
But you can also improve the code to avoid exceptions:
public static <I, O> O cast(I input, Class<O> outClass) {
if(outClass.isAssignableFrom(input.getClass())) {
return outClass.cast(input);
} else {
return null;
}
}
Not really, because this doesn't make any sense. If there's nothing you need to do when you catch the exception, then don't call the operation at all and delete all the code after. If it doesn't matter whether the operation succeeds or fails then don't call it in the first place.
More seriously - ahem, that was serious - you can not catch the exception and let the caller deal with it.
Try to create a common method that does this casting for you
private MyTypeOfObject cast (Object obj) {
try {
// your casting code
return newObj;
} catch (ClassCastException ee) {
// log and ignore
return null; // ????
}
}
There's nothing that I know of to do this (other than what #Scary_Wombat said) but if I were in your shoes I would just write a simple code generator to handle these repetitive/boilerplate cases using some templating engine like Freemarker or something more advanced like Antlr. There are tutorials about the place on each.

Categories

Resources