Thursday, November 24, 2016

C# vs Java : Exception Handling

Features In C# Not Found In Java

default catch block

C# has a "default" catch block. It gets executed when there isn't a catch block that matches with the exception that was thrown.
try {
  Console.WriteLine("try block");

  String str = null;
  str.StartsWith("abc");   
}
catch {
  Console.WriteLine("default catch");
}
The above outputs the following:
try block
default catch

skip labeling the exception

C# doesn't require you to name the exception.
try {
  Console.WriteLine("try block");

  String str = null;
  str.StartsWith("abc");   
}
catch(System.NullReferenceException) {
  Console.WriteLine("catch NullReference");
}

conditional catch blocks

When an exception is thrown, the first catch block that matches the closest to the exception is the one that gets executed. So in the following example the NullReference catch block gets executed instead of the default catch block.
try {
  Console.WriteLine("try block");

  String str = null;
  str.StartsWith("abc");   
}
catch(System.NullReferenceException NullRef) {
  Console.WriteLine("catch NullReference");
}
catch {
  Console.WriteLine("default catch");
}
In C# you can add another layer of specification to your catch blocks. Let's say you only wanted the NullReference catch block to be executed when some flag was true. For all other occurences you want the default catch block to be executed. Here's what that would look like:
try {
  Console.WriteLine("try block");

  String str = null;
  str.StartsWith("abc");   
}
catch(System.NullReferenceException NullRef) when(flag) {
  Console.WriteLine("catch NullReference");
}
catch {
  Console.WriteLine("default catch");
}
Because of conditional catch blocks, you can handle the same exception multiple ways.
try {
  String str = null;
  str.StartsWith("abc");

  Console.WriteLine("try block");
}
catch(NullReferenceException) when (x == 1) {
  Console.WriteLine("catch x == 1");                
}
catch (NullReferenceException) when (x == 2) {
  Console.WriteLine("catch x == 2");
}
catch (NullReferenceException) when (x == 3) {
  Console.WriteLine("catch x == 3");
}
catch {
  Console.WriteLine("default catch");
}

Features In Java Not Found In C#

checked exceptions

Recall that with checked exceptions the compiler checks that you've dealt with them in some way. So for example if you wanted to read data from a text file. The following is what your code might look like:
try {
   String line = null;
   BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
 
   while ((line = reader.readLine()) != null) {
      // process line that was read...
   }
}
catch(java.io.FileNotFoundException fileNotFound) {
   // handle FileNotFoundException
}
catch(java.io.IOException io) {
   // handle IOException
}
finally {
   if(bufferedReader != null) {
      try {
         bufferedReader.close();
      }
      catch(IOException io) {
      }
   }
}
Both FileNotFoundException and IOException are checked exceptions. Unchecked exceptions, like the NullPointerException, typically extend from RuntimeException

state the exceptions a method throws

Recall that there's two ways to handle checked exceptions. You can either handle them in a try-catch block…
try {
   // …
}
catch(IOException io) {
   // …
}
Or you can tack on the throws clause to the end of the method declaration. This basically passes the buck down the road, forcing the code that calls the method to deal with the checked exception.
public void fooBar( ) throws IOException {

Features Found In Both C# and Java

rethrowing exception

Here's how to rethrow an exception in Java:
try {
  System.out.println("try block");

  String str = null;
  str.startsWith("abc");         
}
catch(java.lang.NullPointerException NullPointer) {
  System.out.println("catch NullPointer");

  throw NullPointer;
}
Here's how to rethrow an exception in C#:
try {
  Console.WriteLine("try block");

  String str = null;
  str.StartsWith("abc");
}
catch(System.NullReferenceException NullRef)  {
  Console.WriteLine("catch NullReference");

  throw;
}

reuse same catch block for multiple exceptions

Here's how, in Java, you can catch multiple exceptions in one catch block. Note that neither IOException nor IllegalArgumentException are subclasses of each other.
catch(IOException | IllegalArgumentException exception) {
}
Here's how to do the same thing in C#
catch (Exception ex) when (ex is IOException || ex is ArgumentException) {                
}

working with resources

There's a feature in both C# and Java that will automatically close a resource once you're done using it. In Java you use the try-with-resources, like so:
try(BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {
   String line = null;
    
   while ((line = reader.readLine()) != null) {
      // process line that was read...
   }
}
catch(FileNotFoundException fileNotFound) {
   // handle FileNotFoundException
}
catch(IOException io) {
   // handle IOException
}
In C# you use the using statement.
using(StreamReader streamReader = new StreamReader(strFilePath)) {
  String line = null;

  while((line = file.ReadLine()) != null) {
    // process line that was read...    
  }
}

References

Understanding JDK 7 - try-with-resources
Catch multiple exceptions at once?
C# 6.0 Features
8.13 The using statement
Exception Handling (C# Programming Guide)
try-catch (C# Reference)
Exceptions (C# vs Java)

No comments:

Post a Comment