How to use reflection mechanisms to invoke a public method that resides in a base class with default visibility?

StackOverflow https://stackoverflow.com/questions/8070121

質問

This question concerns the reflection mechanisms of the java programming language.

I have an interface:

package A;

public interface MyInterface {

    public boolean doSomething(Object... parameters);
}

I have several implementation classes for this interface. Here some examples:

package B;
import A.*;

abstract class BaseImplementation implements MyInterface {

    private Object field;

    protected BaseImplementation() {

        super();
    }

    public void setField(Object aField) {

        field = aField;
    }

    public Object getField() {

        return field;
    }
}

package B;
import A.*;

public class ConcreteImplementation extends BaseImplementation {

    public ConcreteImplementation() {

        super();
    }

    ...

    // The concrete implementation provides an implementation for all
    // inherited abstract methods. Apart from this no other methods
    // are overridden.
    // This concrete class provides accessor methods for all of its own
    // private fields.

    ...
}

(edited) As a sidenote (this may not be relevant to the issue concerning the reflection mechanism):

I'm implementing a complex ruleset. One drawback of this ruleset is that there are lots of interdependencies between objects. Thus there is a need to define the general behaviour with interfaces. When implementing one part of the ruleset you have to consider the behaviour of another, not yet implemented, part.

Different implementations of an interface require different resources/objects to work properly. To reduce duplicate code I use the abstract parent classes. These abstract classes are not used outside of their packages.

When instantiating and initializing an instance of a concrete implementation class I resort to reflection mechanisms. For this purpose I have a utility class (which resides in a separate package) where I have to specify the desired classname, which field gets which value (i.e. the appropriate setter methods will be looked up then) and the order in which the setter methods are called.

I have two different development environments and on each a different version of java is installed (1.5.x and 1.6.x). This is mainly used for cross checking the behaviour of the implementation.

Instantiating an instance of a concrete implementation class works in both environments. But the initialization fails with the older java version. Somehow the public setter method of the base class (the base class has a default visibility) cannot be accessed. The newer java version has no issues with accessing the setter method.

One workaround I found is to change the visibility of the base class (default -> public). The question is, is there a way to keep the visibility (default) and still call the setter method with reflection mechanisms?

役に立ちましたか?

解決

Depending on what security restrictions you have in place you can use

AccessibleObject.setAccessible(boolean);

(AccessibleObject is an interface implemented by Field, Method, Constructor). Before your reflections call just invoke method.setAccessible(true); on the reflections object and unless the SecurityManager throws an Exception you should be fine.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top