Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I override a hidden (but public) method and call its super method?

There is a non public api that I need to override in order to workaround a quirk with Android's WebView.

The api is hidden but it is public:

/**
 * ...
 *
 * @hide pending API council approval
 */
public boolean selectText() {
    ...
}

So I can override it by simply declaring it in my own WebView class, minus the @Override:

public boolean selectText() {
    ...
}

Is it possible to call the super method from my override? Normally I could write:

public boolean selectText() {
    return super.selectText();
}

But the method is hidden, so super.selectText() is not available. If I use reflection:

public boolean selectText() {
    return (Boolean) WebView.class.getMethod("selectText").invoke(this, (Object[]) null);
}

I get an infinite loop because it calls my overridden method.

Is there anyway to override this method AND be able to call the super method?

Thanks!

like image 614
cottonBallPaws Avatar asked Mar 23 '12 18:03

cottonBallPaws


1 Answers

  1. YES You CAN :) - first part of question
  2. NO You CAN'T - second one

solution 1) - best what you can do here closest to what you want to achieve

// to override method 
// which IDE doesn't see - those that contains {@ hide} text in JavaDoc
// simple create method with same signature
// but remove annotation
// as we don't know if method will be present or not in super class 
//
//@Override      
public boolean callMethod(String arg) {

    //  can we do it ?
    // boolean result = super.callMethod(arg)
    // no  why ? 
    // You may think you could perhaps
    // use reflection and call specific superclass method 
    // on a subclass instance.


/** 
 * If the underlying method is an instance method, it is 
 * invoked using dynamic method lookup as documented in The 
 * Java Language Specification, Second Edition, section 
 * 15.12.4.4; in particular, overriding based on the runtime
 * type of the target object will occur.
 */


   // but always you can see what super class is doing in its method 
   // and do the same by forward call in this method to newly created one
   // return modified  result 
  return doSomthingWhatSuperDo()
}

solutions 2)

does the object (which calls this method) belongs to you? and implements interface?

if so how about proxy ?

  1. extend class
  2. create proxy
  3. use proxy
  4. intercept method call
  5. based on some conditions ? call own implementation or fall back to originally?
like image 102
ceph3us Avatar answered Oct 13 '22 19:10

ceph3us