簡體   English   中英

通過反射在不同包中的類上調用公共方法

[英]Invoking public method on a class in a different package via reflection

我遇到了以下問題。

我在包a有兩個不同的包,我想在包b調用接口的實現方法,但是實現類具有包可見性。

因此,簡化的代碼如下所示:

package b;

public final class Factory {
    public static B createB() {
        return new ImplB();
    }

    public interface B {
        void method();
    }

    static class ImplB implements B {
        public void method() {
            System.out.println("Called");
        }
    }
}

和調用者:

package a;

import java.lang.reflect.Method;
import b.Factory;
import b.Factory.B;

public final class Invoker {
    private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[] {};
    private static final Object[] EMPTY_OBJECT_ARRAY = new Object[] {};

    public static void main(String... args) throws Exception {
        final B b = Factory.createB();
        b.method();

        final Method method = b.getClass().getDeclaredMethod("method", EMPTY_CLASS_ARRAY);
        method.invoke(b, EMPTY_OBJECT_ARRAY);
    }
}

當我啟動程序時,它會按預期打印出Called並拋出異常,因為程序包的可見性禁止調用發現的方法。

所以我的問題是解決這個問題的任何方法嗎? 我是否在Java文檔中缺少某些內容,或者根本不可能做到這一點,盡管僅需調用一個實現的方法就可以了,而無需反思。

由於類具有程序包可見性,因此其方法的可見性實際上是程序包級別,而不是您認為的公共級別。 因此,您必須在方法調用之前調用method.setAccessible(true)

 final Method method = b.getClass().getDeclaredMethod("method", EMPTY_CLASS_ARRAY);
 method.setAccessible(true);
 method.invoke(b, EMPTY_OBJECT_ARRAY);

我知道了 我需要在實現的接口上而不是在類上調用getDeclaredMethod

例:

final Method method = B.class.getDeclaredMethod("method", EMPTY_CLASS_ARRAY);
method.invoke(b, EMPTY_OBJECT_ARRAY);

請參閱文檔setAccessible 但是,SecurityPolicy可能會阻止您對其進行訪問。

但是尚不清楚您是否需要反思。 多態性的好處之一是客戶端可以調用B.method()而無需訪問(甚至擔心)實現接口的具體類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM