0

2 つの異なるパッケージがあると仮定します... 1 つのパッケージにはアクセスできませんが、b という複雑なフィールドの値を知りたいとします。

public class A {
    private String  whatever;
    private B       b;

    private static class B {
         final ArrayList<Z> c   = new ArrayList<Z>();

         private void addItem(Z z) {
                this.c.add(z);
         }

         private Z getItem(int nr) {
                return this.c.get(nr);
          }
     }
}

public class Reflect extends A {
      public static void main(String[] args) throws NoSuchFieldException, SecurityException {
            Reflect ref = new Reflect();
            Class getA = ref.getClass().getSuperclass();
            Field getB = getDeclaredField("b");
            getB.setAccessible(true);
            Class bInst = getB.getClass();
            Method bMeth = bInst.getMethod("getItem", Integer.TYPE);
            Object zInst = bMeth.invoke(new Integer(123));
      }
}

パッケージから複合型 B を取得できない場合、どうすれば値を取得できますか? フィールド gstB をアクセス可能に設定しても、 java.lang.NoSuchMethodException: stackOver.A.getItem(int)を取得します ....

4

3 に答える 3

2

パッケージから複合型 B を取得できない場合、どうすれば値を取得できますか?

として取得し、Objectリフレクションを使用して、それが公開するメソッドをさらに発見できます。

Object bInst = ... // Get b through reflection
Class bClass = bInst.getClass();
Method[] bMeth = bClass.getMethod("getItem", Integer.TYPE);
Object zInst = bMeth.invoke(new Integer(123));
于 2013-01-27T17:08:27.773 に答える
2

あなたが見逃している唯一のことは、 getField がパブリックにアクセス可能なフィールドのみを提供することです。

 Field getB = getA.getDeclaredField("b");

そのクラスの任意のフィールドを提供します。


より長い例

class Main {
    public static class A {
        private String whatever;
        private B b = new B();

        private static class B {
            final ArrayList<String> c = new ArrayList<String>();

            private void addItem(String z) {
                this.c.add(z);
            }

            private String getItem(int nr) {
                return this.c.get(nr);
            }
        }
    }

    public static class Reflect extends A {
        public static void main(String... ignored) throws Exception {
            Reflect ref = new Reflect();
            Class getA = ref.getClass().getSuperclass();
            Field getB = getA.getDeclaredField("b");
            getB.setAccessible(true);
            Object b = getB.get(ref);

            Method addItem = b.getClass().getDeclaredMethod("addItem", String.class);
            addItem.setAccessible(true);
            addItem.invoke(b, "Hello");

            Method getItem = b.getClass().getDeclaredMethod("getItem", int.class);
            getItem.setAccessible(true);
            String hi = (String) getItem.invoke(b, 0);
            System.out.println(hi);
        }
    }
}

版画

Hello
于 2013-01-27T17:34:33.240 に答える
1

commons beanutils ライブラリを使用し、次の方法を使用します。自分で行うよりもはるかにクリーンです。

PropertyUtils.getNestedProperty(ref, "b.propertyOfClassB");

propertyOfClassB を実際のプロパティ名に置き換えます。

于 2013-01-27T17:37:55.153 に答える