Clojureの(bean obj)
を使用して、オブジェクトに関連する不変のマップを取得しようとしています。 Clojureの1.4.0標準ライブラリでjava.bean APIを使用して非公開クラスのインスタンスを検査する
が、これは大体そう(Clojureのに慣れていない人々へのアクセス意図擬似コードに変換する)のように実装されている:
import java.beans.PropertyDescriptor;
import java.beans.Introspector;
function introspect(Object obj) {
Class clazz = obj.getClass();
PropertyDescriptor descriptors[] =
Introspector
.getBeanInfo(clazz)
.getPropertyDescriptors();
Map retval = new HashMap();
for(pd in descriptors) {
name = pd.getName();
method = pd.getReadMethod();
if(method.getParameterTypes().length != 0)
continue;
retval.set(name, method.invoke(obj, nil));
}
/* the real implementation does more magic below here,
but the above is sufficient for this question */
return retval;
}
ほとんどの部分については、これが正常に動作します - java.bean.IntrospectorデフォルトのBeanInfo実装の非公開メソッドは返されません。しかし、検査されているオブジェクトが非publicクラスのインスタンスである場合、実際に呼び出すことはできませんが、IllegalArgumentException
( "非公開のpublicメソッドを呼び出すことはできません。パブリッククラス ")。
どのようにこれを修正できますか? java.lang.Classのドキュメントを見ていますが、try/catchブロックが含まれていないクラスのアクセス許可を判断する明白な方法は表示されませんjava.lang.SecurityException ...正確には私には当てはまりませんベストプラクティスさらに、非publicクラスのメソッドがパブリックインターフェイスを実装する場合、このメソッドが安全に呼び出せるかどうかを判断するためのいくつかのメカニズムが利用可能である必要があります。
残念ながら、プライベートクラスがパブリックインターフェイスを実装する場合、この回答は、そのインターフェイスで定義されたメソッドがアクセス可能であることを判断するのには十分ではありません。 PropertyDescriptorからインタフェースを識別する方法と併せて、おそらくそれで十分でしょう。 –
オブジェクトがインターフェイスを実装するクラス(定義によってパブリック)である場合、クラスのプライバシーに関係なくインターフェイス上のメソッドを呼び出すことができるはずです。それ以外はバグです。 Javaには、内部クラスが言語に追加されたために多くの不必要な手荷物があることに注意してください。プライベートクラスは内部クラスとしてのみ意味があります。あなたの例の構造に、私が紛失しているものがあるかもしれません。 – sw1nn
私はいくつかのパブリックメソッドを持つ非公開クラスを持っています。これらのメソッドのいくつかは、インターフェイスを実装するクラスのおかげで公に呼び出すことができます。それらのパブリック・メソッドのいくつかは、パブリック・クラスまたはインタフェースでは定義されていないため、非パブリック・クラス自体でのみ定義されるため、呼び出すことができません。これを動かす実際のユースケースは、Jiraで使用されるAtlassianのCrowd製品の 'com.atlassian.crowd.embedded.ofbiz.OfBizUser'です。私は非公開のクラスでパブリックメソッドを持つのは意味がないと思うが、私の唯一のコントロールはそれを示唆するチケットを提出することだ。 –