Not true for Java about Function Hijacking.

Dan Olson zans.is.for.cans at yahoo.com
Thu May 26 00:57:38 PDT 2011


I recall specific cases, though, in which hijacking can happen in java.  I
coded them up to make sure I remembed it correctly.  Imagine a base
class A and subclass B.

=-=-= file A.java =-=-= 
public class A {
       // pretty boring
}

=-=-= file B.java =-=-=
public class B extends A {
   private void foo(long x) {
      System.out.println("B.foo(long)");
   }

   private void put(Object o) {
      System.out.println("B.put(Object)");
   }

   public void doStuff() {
      foo(0xcafebabe);
      put(this);
   }

   public static void main(String[] args) {
      B b = new B();
      b.doStuff();
   }
}

As is, doStuff() prints:

B.foo(long)
B.put(Object)


But in a new version of the base class A, some new methods are added
that are intended to be overriden.

public class A {
    // These methods are added later and hijack B's methods because they
    // match better
    public void foo(int x) {System.out.println("A.foo(int)");}
    public void put(A a) {System.out.println("A.foo(A)");}
}

Because they are a better match for the arg types in doStuff(), they are
called instead.  But that's not what the designer of class B intended :-(

It compiles with javac without warning.  Now the output from doStuff()
is:

A.foo(int)
A.foo(A)


----
// Opposite case.  A subclass hijacks functions of a base class

class X {
    // launch is a new function that a designer intended to be
    // overridable.  But the designer has no way of knowing that launch() 
    // is already implemented in a subclass somewhere (some other 
    // company perhaps), and it does something completely different.

    public void launch(int x) {
        // Launch application ID x
        System.out.println("X.launch app id " + x);
    }

    public void cleanup() {
        launch(42);
    }
}

// When class Y was designed, X didn't have a launch method

class Y extends X {
    // If @Override keyword was required for overrides, then this
    // would be flagged.  Or at least provide a switch to warn about this.
    public void launch(int sec) {
        // Launch the missle in 'sec' seconds
        System.out.println("Y.launch missle in " + sec + " sec");
    }

    public static final void main(final String[] args) {
       Y y = new Y();
        y.cleanup();
    }
}

Mathew, it sounds like netbeans flags this case, but I think it will go
unnoticed if your builds are done with something like ant and javac.

-- 
Dan Olson


More information about the Digitalmars-d-learn mailing list