samedi 6 juillet 2019

How to type cast via reflection when the class is package private

First, this is similar to this question but there was never a satisfactory answer. Second: I know, I know, reflection is bad, but it is the only option I have.

Question: Given a class

package a.pkg.outside.my.code;

class ClassIWant {   // Package private class
    public ClassIWant instance() {...}
}

I want to call instance(), obtaining an instance of ClassIWant, and return a ClassIWant (not an Object).

I can successfully call instance via reflection and get my hands on an Object:

public class MyClass {
    /* type var T will always take value ClassIWant. I can currently get
     * get this to type check by using Class.cast and changing return
     * type to T, but this doesn't solve my problem.
     */
    public ClassIWant <T> callInstance() {  // Here T is ClassIWant
        Object result = _use reflection_;
        return (ClassIWant) result;         // Fails at runtime
    }
}

The issue is that I don't have access to ClassIWant to cast, and the best I've been able to do is call clazz.cast(result). This returns type T, which doesn't quite do what I want.

It's not even clear to me that this is possible, but my program has been type checking and getting illegal access errors at runtime. This tells me that all the bits and pieces fit together on the type level, and that methods are all pointing to the right place.

Note: It may be possible to change my use case to not need an explicit ClassIWant, but this would probably be a fair amount of work (i.e., lots and lots of calls to reflection). For brevity I haven't included the use case---I'll treat this as a second question if need be.





Aucun commentaire:

Enregistrer un commentaire