これらは, Java のクラス内のメソッド情報やフィールド情報にアクセスするためのユーティリティ・クラス.
指定したクラスを起点として, そのスーパークラスやスーパーインターフェースを辿っていくためのイテレータクラス(ValueObjクラス) (の基底クラス).
なお, このクラス自体は abstract class であり, 実際に使われるのはサブクラス.
((cite: hotspot/src/share/vm/runtime/reflectionUtils.hpp))
// A KlassStream is an abstract stream for streaming over self, superclasses
// and (super)interfaces. Streaming is done in reverse order (subclasses first,
// interfaces last).
//
// for (KlassStream st(k, false, false); !st.eos(); st.next()) {
// klassOop k = st.klass();
// ...
// }
class KlassStream VALUE_OBJ_CLASS_SPEC {
See: here for details
指定したクラスを起点として, そのスーパークラスやスーパーインターフェースのメソッドを辿っていくためのイテレータクラス(ValueObjクラス).
((cite: hotspot/src/share/vm/runtime/reflectionUtils.hpp))
// A MethodStream streams over all methods in a class, superclasses and (super)interfaces.
// Streaming is done in reverse order (subclasses first, methods in reverse order)
// Usage:
//
// for (MethodStream st(k, false, false); !st.eos(); st.next()) {
// methodOop m = st.method();
// ...
// }
class MethodStream : public KlassStream {
以下の箇所で(のみ)使用されている.
See: here for details
指定したクラスを起点として, そのスーパークラスやスーパーインターフェースのフィールドを辿っていくためのイテレータクラス(ValueObjクラス).
((cite: hotspot/src/share/vm/runtime/reflectionUtils.hpp))
// A FieldStream streams over all fields in a class, superclasses and (super)interfaces.
// Streaming is done in reverse order (subclasses first, fields in reverse order)
// Usage:
//
// for (FieldStream st(k, false, false); !st.eos(); st.next()) {
// Symbol* field_name = st.name();
// ...
// }
class FieldStream : public KlassStream {
以下の箇所で(のみ)使用されている.
See: here for details
特殊な FieldStream クラス.
FieldStream と異なり, HotSpot の内部処理用のフィールドはスキップする.
((cite: hotspot/src/share/vm/runtime/reflectionUtils.hpp))
// A FilteredFieldStream streams over all fields in a class, superclasses and
// (super)interfaces. Streaming is done in reverse order (subclasses first,
// fields in reverse order)
//
// Usage:
//
// for (FilteredFieldStream st(k, false, false); !st.eos(); st.next()) {
// Symbol* field_name = st.name();
// ...
// }
class FilteredFieldStream : public FieldStream {
以下の箇所で(のみ)使用されている.
スキップするかどうかの判定は FilteredFieldsMap クラスが行っている.
(より正確に言うと FilteredFieldsMap クラスの FilteredFieldsMap::is_filtered_field() メソッドが行っている. FilteredFieldsMap::is_filtered_field() が true を返す場合は, そのフィールドをスキップして次のフィールドに進む)
See: here for details
See: here for details
FilteredFieldStream クラス用の補助クラス.
FilteredFieldStream の処理でスキップしたいフィールドを管理するためのクラス (より正確には, そのための機能を納めた名前空間(AllStatic クラス)).
((cite: hotspot/src/share/vm/runtime/reflectionUtils.hpp))
class FilteredFieldsMap : AllStatic {
以下の箇所で(のみ)使用されている.
* このクラスの初期化処理 javaClasses_init() -> FilteredFieldsMap::initialize() * FilteredFieldStream の処理 FilteredFieldStream::FilteredFieldStream() -> FilteredFieldsMap::filtered_fields_count() FilteredFieldStream::next() -> FilteredFieldsMap::filtered_fields_count() FilteredFieldStream::next() -> FilteredFieldsMap::is_filtered_field() * GC 処理 (より正確に言うと GC 時に FilteredFieldsMap 内に格納しているポインタを辿る処理) SystemDictionary::preloaded_oops_do() -> FilteredFieldsMap::klasses_oops_do()
実際のスキップ対象の情報は FilteredField オブジェクトが格納している.
((cite: hotspot/src/share/vm/runtime/reflectionUtils.hpp))
private:
static GrowableArray<FilteredField *> *_filtered_fields;
現在は, 以下の三つのフィールド(のみ)をスキップ対象としている.
java.lang.Throwable.backtrace
このフィールドは, ソースコード上では Object 型になっているが, 実際には Java のオブジェクトではなく HotSpot の内部的なデータ構造が納められているため除外されている (参考).
sun.reflect.ConstantPool.constantPoolOop (JDK 6 以降の場合のみ)
除外されている理由は恐らく java.lang.Throwable.backtrace フィールドと同様 (#TODO).
sun.reflect.UnsafeStaticFieldAccessorImpl.base (JDK 6 以降の場合のみ)
除外されている理由は恐らく java.lang.Throwable.backtrace フィールドと同様 (#TODO).
((cite: hotspot/src/share/vm/runtime/reflectionUtils.cpp))
void FilteredFieldsMap::initialize() {
...
offset = java_lang_Throwable::get_backtrace_offset();
_filtered_fields->append(new FilteredField(SystemDictionary::Throwable_klass(), offset));
// The latest version of vm may be used with old jdk.
if (JDK_Version::is_gte_jdk16x_version()) {
// The following class fields do not exist in
// previous version of jdk.
offset = sun_reflect_ConstantPool::cp_oop_offset();
_filtered_fields->append(new FilteredField(SystemDictionary::reflect_ConstantPool_klass(), offset));
offset = sun_reflect_UnsafeStaticFieldAccessorImpl::base_offset();
_filtered_fields->append(new FilteredField(SystemDictionary::reflect_UnsafeStaticFieldAccessorImpl_klass(), offset));
}
}
See: here for details
FilteredFieldsMap クラス内で使用される補助クラス.
FilteredFieldStream の処理でスキップしたいフィールドを表すクラス. 1つの FilteredField オブジェクトが 1つのフィールドに対応する.
((cite: hotspot/src/share/vm/runtime/reflectionUtils.hpp))
class FilteredField {
FilteredFieldsMap クラスの _filtered_fields フィールド (static フィールド) に(のみ)格納されている.
(正確には, このフィールドは FilteredField の GrowableArray を格納するフィールド. この中に, 全ての FilteredField オブジェクトが格納されている)
FilteredFieldsMap::initialize() 内で(のみ)生成されている.
以下の箇所で(のみ)使用されている.
定義されているフィールドは以下の通り (そして, メソッドはこれらのフィールドへのアクセサメソッドのみ).
(それぞれ, フィルタリング対象のクラス, およびそのフィールドのオフセットを表す)
((cite: hotspot/src/share/vm/runtime/reflectionUtils.hpp))
klassOop _klass;
int _field_offset;
See: here for details
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.