Java override exception extension

Suppose we have two classes:

Grade A:

import java.io.IOException; public class A { public void test() throws IOException{ System.out.println("test in A"); } } 

Grade B:

  import java.io.IOException; public class B extends A { @Override public void test() throws Exception{ System.out.println("test in B"); } } 

This gives a compiler error, and I would like to know the reason for this. I can get the answer myself, but this is not completely scientific, but partially logical.

I wrote a blog post in Azerbaijani . When I wrote a blog, I was stuck in the download process.

Please be careful with quotation marks:

I think that when the compiler reads class B, it loads the headers of the header methods A and methods B. And when you call test A, the JVM calls test A, but as a test for calls to body B, and at this time we will have this method:

  public void test() throws IOException{ // <-- Header of A System.out.println("test in B"); // <-- Body of B // Here I can throw wide Exception from IOException // because here is the body of the test in B. The test // method in B can throw Exception so the compiler // doesn't approve of this version of the code. } 

Is the process really ongoing, like what I wrote above?

Download question headers I'm stuck here. How does the binding process work? I can not determine the background

 A a = new B(); // When the compiler converts this line into bytecode // does it loads of method headers of A and method // body of B a.test() 

calls a class B test. I know logically, but I cannot understand at the compiler level, binding the process.

+6
source share
3 answers

Imaigine you have the following code:

 A a = new B(); try { a.test(); } catch (IOExceoption e) { //do some specific handle for IOExceoption } 

Now change what happens if b.test() type an Exception , which is NOT an IOException ? no one can handle this and this will break the java mechanism of checked exceptions .


Another way, however, is fine:

 public class A { public void test() throws Exception { System.out.println("test in A"); } } public class B extends A { @Override public void test() throws IOException{ System.out.println("test in B"); } } A a = new B(); try { a.test(); } catch (Exception e) { //handle } 

Now notice that catch handles a general Exception , including a specific IOException , and the code will compile fine.

+9
source

A hidden method can throw everything that is an IOException exception. Or, more generally, it can throw any exception that is a ParentException. So you can throw a FileNotFoundException , as this is also an IOException .

Why?

Failure to comply with this rule violates the main contract between the parent-child in inheritance.

Somewhere in your code, you can safely assume that the exception raised by the test() call will always be an IOException, no matter which implementation of A throws it. If you were allowed to throw an InterruptedException in your case, what exception should the caller throw?

The compiler does not load anything. It simply marks the method as invoke virtual, which means that this method is overridden and should be called at runtime based on the type of the object

+3
source

From a slightly different angle, you basically do not override the existing method in the super type.

The exceptions that are thrown are part of the method signature. When you declare your test method in class B with an override annotation, you are actually trying to override (or implement) a method that does not exist in its parent A.

+2
source

Source: https://habr.com/ru/post/985507/


All Articles