jeudi 25 avril 2019

Use of private class as method parameter using reflection and cast when invoking the method

I know I can instantiate an object of a non-visible class using reflection. That will give me an object of type Object. But can I make a non-visible class visible?

In my case I want to change handleB by modifying a switch-case-statement:

package packageOne;
public class A {
       B b;
   public A(int a) {
       ...
       b = new B(1,2);
       handleB(b);
   }

   handleB(final B b) {
       switch(b.getName()) {
       case "Hello":
           doSomething();
           break;
       case "Foo":
           doSomethingElse();
           break;
       case "Bar":
           doItBetter();
           break;
   }
}

While B is a non-visible class in the same package.

package packageOne;
final class B {
    private String name;
    public B(int one, int two) {
        this.name = ... //whatever
    }
    public String getName() {
        return name;
    }
}

My class resides in another package, but extends A. I want to modify its protected method handleB by copying it and (its caller methods) to My class. Now to call handleB I don't need reflection, because I have that method in my own class. But B is in its parameter list and B is invisible to MyClass.

I'll put the reflection part in its constructor:

package packageTwo;
public class MyClass {
    // private B myB; not possible, since B is invisible
    private Object myB;

    public MyClass() extends A {
        Class<?> c = Class.forName("packageOne.A");
        fBField = c.getDeclaredMethod("handleB");
        fBField.setAccessible(true);

        myB = fBField.get(this);
        // How can I cast myB to type `B` when I don't know what `B` is?
        handleB(myB); //refers to missing type B
   }

   handleB(final B b) { //missing type B
       switch(b.getName()) {
       case "Hello":
           doSomethingElse();
           break;
       case "Foo":
           doItBetter();
           break;
       case "Bar":
           doSomething();
           break;
   }
}

So I need a way to declare a variable and parameter of type B. Is that possible using reflection or any other way? Is there another possibility to modify the package-private method?





Aucun commentaire:

Enregistrer un commentaire