Java Reflectionです。Javaクラスのすべてのゲッターメソッドを取得して呼び出すには?
2023-09-03 16:32:35
質問
私は多くのゲッターを持つJavaクラスを書きました。私はすべてのゲッターメソッドを取得し、いつかそれらを起動したい。
どのように解決するには?
正規表現を使用せずに
Introspector
:
for(PropertyDescriptor propertyDescriptor :
Introspector.getBeanInfo(yourClass).getPropertyDescriptors()){
// propertyEditor.getReadMethod() exposes the getter
// btw, this may be null if you have a write-only property
System.out.println(propertyDescriptor.getReadMethod());
}
通常、Object.classのプロパティは必要ないので、2つのパラメータを持つメソッドを使用します。
Introspector.getBeanInfo(yourClass, stopClass)
// usually with Object.class as 2nd param
// the first class is inclusive, the second exclusive
ところで、このようなことを代わりにやってくれて、ハイレベルなビューを提示してくれるフレームワークがあります。例えば commons/beanutilsにはメソッドがあります。
Map<String, String> properties = BeanUtils.describe(yourObject);
(
ドキュメントはこちら
) はまさにそれを行います: すべてのゲッターを見つけて実行し、結果をマップに格納します。残念ながら
BeanUtils.describe()
は返す前にすべてのプロパティの値を文字列に変換します。ワロタ。ありがとう @danw
更新しました。
ここでは、Java 8 のメソッドで
Map<String, Object>
をオブジェクトのビーンプロパティに基づいて返すJava 8のメソッドです。
public static Map<String, Object> beanProperties(Object bean) {
try {
return Arrays.asList(
Introspector.getBeanInfo(bean.getClass(), Object.class)
.getPropertyDescriptors()
)
.stream()
// filter out properties with setters only
.filter(pd -> Objects.nonNull(pd.getReadMethod()))
.collect(Collectors.toMap(
// bean property name
PropertyDescriptor::getName,
pd -> { // invoke method to get value
try {
return pd.getReadMethod().invoke(bean);
} catch (Exception e) {
// replace this with better error handling
return null;
}
}));
} catch (IntrospectionException e) {
// and this, too
return Collections.emptyMap();
}
}
おそらく、エラー処理をより強固なものにしたいのでしょう。定型文で申し訳ありませんが、チェックされた例外がここで完全に機能することを妨げています。
Collectors.toMap() は null 値を嫌うことがわかりました。以下は、上記のコードのより命令的なバージョンです。
public static Map<String, Object> beanProperties(Object bean) {
try {
Map<String, Object> map = new HashMap<>();
Arrays.asList(Introspector.getBeanInfo(bean.getClass(), Object.class)
.getPropertyDescriptors())
.stream()
// filter out properties with setters only
.filter(pd -> Objects.nonNull(pd.getReadMethod()))
.forEach(pd -> { // invoke method to get value
try {
Object value = pd.getReadMethod().invoke(bean);
if (value != null) {
map.put(pd.getName(), value);
}
} catch (Exception e) {
// add proper error handling here
}
});
return map;
} catch (IntrospectionException e) {
// and here, too
return Collections.emptyMap();
}
}
同じ機能をより簡潔にするため、以下のように JavaSlang :
public static Map<String, Object> javaSlangBeanProperties(Object bean) {
try {
return Stream.of(Introspector.getBeanInfo(bean.getClass(), Object.class)
.getPropertyDescriptors())
.filter(pd -> pd.getReadMethod() != null)
.toJavaMap(pd -> {
try {
return new Tuple2<>(
pd.getName(),
pd.getReadMethod().invoke(bean));
} catch (Exception e) {
throw new IllegalStateException();
}
});
} catch (IntrospectionException e) {
throw new IllegalStateException();
}
}
そして、こちらはGuava版です。
public static Map<String, Object> guavaBeanProperties(Object bean) {
Object NULL = new Object();
try {
return Maps.transformValues(
Arrays.stream(
Introspector.getBeanInfo(bean.getClass(), Object.class)
.getPropertyDescriptors())
.filter(pd -> Objects.nonNull(pd.getReadMethod()))
.collect(ImmutableMap::<String, Object>builder,
(builder, pd) -> {
try {
Object result = pd.getReadMethod()
.invoke(bean);
builder.put(pd.getName(),
firstNonNull(result, NULL));
} catch (Exception e) {
throw propagate(e);
}
},
(left, right) -> left.putAll(right.build()))
.build(), v -> v == NULL ? null : v);
} catch (IntrospectionException e) {
throw propagate(e);
}
}
関連
-
-bash: java: コマンドが見つからない 解決方法
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] Javaにおけるpublic、protected、package-private、privateの違いは何ですか?
-
[解決済み] プライベートメソッド、フィールド、インナークラスを持つクラスをテストするにはどうすればよいですか?
-
[解決済み] Javaで配列を宣言し、初期化する方法は?
-
[解決済み] Javaで文字列値からenum値を取得する方法
-
[解決済み] Java内部クラスと静的ネストされたクラス
-
[解決済み] Javaで現在のスタックトレースを取得するにはどうすればよいですか?
-
[解決済み】JSP 2を使用して、JSPファイル内のJavaコードを回避するにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
NullPointerException - java.lang.
-
アクセス制限です。タイプ 'JPEGCodec' は API ではない ☞My Blog Github ☜ ホームページを見る
-
スレッド "main" での例外 java.lang.ArrayIndexOutOfBoundsException:5 エラー
-
が 'X-Frame-Options' を 'sameorigin' に設定したため、フレーム内に存在する。
-
シェルコマンドやスクリプトのJavaコール
-
CertificateException: XXXに一致するサブジェクトの代替DNS名が見つかりません 解決策
-
Junitのユニットテストエラー
-
Javaがリソースリークに遭遇した:'input'が閉じない 解決方法
-
Server Tomcat v9.0 Server at localhost の起動に失敗しました。
-
[解決済み】Collectors.toMapでNullPointerExceptionが発生する。