Two rights can make a wrong...
Careful considered subclassing combined with helpfull overloading can easily lead to this:
java.lang.StackOverflowError at java.lang.String.<init>(String.java:422) at java.lang.StringBuffer.toString(StringBuffer.java:1225) at test.TestSub.act(Main.java:23) at test.TestBase.act(Main.java:36) at test.TestSub.act(Main.java:27) at test.TestSub.act(Main.java:23) at test.TestBase.act(Main.java:36) ....
Code snippet to play this game at home:
8 package test; 9 14 public class Main { 15 16 public static void main(String[] args) { 17 (new TestSub()).act(5); 18 } 19 } 20 21 class TestSub extends TestBase{ 22 public void act(int i) { 23 act(""+i); //changing this to super.act(i) solves the problem! 24 } 25 26 public void act(String s) { 27 super.act(s); 28 } 29 } 30 31 class TestBase { 32 public void act(int i){ 33 System.out.println(i); 34 } 35 public void act(String s){ 36 act(Integer.parseInt(s)); 37 } 38 }
Lesson to learn:
- If you have overloaded methods in a class that is to be subclassed (not final) then you should make sure that the javadoc going with it clearly states how the internal overloading is done.
- If you are overriding methods, always check the baseclass javadoc for overloaded side-effects like this. And delegate to super instead of to an overloaded version on the same level.
By the way I got to learn this the hard way making my own XMLFilter with overriden: XMLFilterImpl.parse(String SystemId) AND XMLFilterImpl.parse(InputSource input). The resolution is snap, the insight is immediate, the bite was nevertheless unexpected.
11:21:42 AM
|