簡體   English   中英

通過反射獲取Java中的成員變量值的陷阱

[英]Pitfalls in getting member variable values in Java with reflection

我有一個抽象類,如下所示。 我想獲取成員變量的所有值。

public abstract class PARAMS {
    public static final String NAME1 = "VAL1";
    public static final String NAME2 = "VAL2";
    public static final String NAME3 = "VAL3";
}

使用反射按如下方式檢索值。

Field[] fields = PARAMS.class.getFields();
for (Field field : fields) {
    String name = field.getName() ;
    String value = (String) field.get(name);
}

這是我第一次嘗試反射。 這是實現目標的正確方法嗎? 我想知道在這種情況下使用反射的陷阱是什么。

您可以靜態字段和私有字段進行代碼迭代。 因此,您應該檢查是否僅對靜態字段進行迭代。

for (Field field : PARAMS.class.getFields()) {
    if (Modifiered.isStatic(field.getModifiers())) continue;
    String name = field.getName() ;
    String value = (String) field.get(PARAMS.class);
}

注意: 正如Jon所述,對於靜態字段訪問,實例參數將被忽略。 但是,我更喜歡傳入類而不是null,因為這是縮進的更好文檔。

但是,更好的做法是使用注釋對字段進行注釋,以便僅獲取您確實不希望其他程序員(甚至幕后的Java語言)添加的其他靜態字段的那些字段。 如果這樣做,您的代碼將如下所示

for (Field field : PARAMS.class.getFields()) {
    if (!field.isAnnotationsPresent(YourAnnotation.class)) continue;
    String name = field.getName() ;
    String value = (String) field.get(PARAMS.class);
}

這不是很正確-出於可讀性的考慮, get參數在理想情況下應為null :該參數的目的是為您檢索實例字段時提供目標。

因此,您的代碼可以只是:

Field[] fields = PARAMS.class.getFields();
for (Field field : fields) {
    String name = field.getName() ;
    String value = (String) field.get(null);
}

現在,這應該可行...但是您將如何處理這些值? 有什么理由為什么要這樣做,而不是創建直接暴露的不可變Map<String, String>

在需要的地方可以進行反思,但是您沒有提供足夠的信息來確定在這種情況下是否真正必要。

另一個問題, getFields返回此類及其所有超類的所有可訪問字段(是否為靜態)。 對於您發布的特定代碼而言,這不是問題,因為唯一的超類是沒有公共字段的Object
我至少會測試該字段是否在正確的類getDeclaringClass()聲明,以及它是否具有正確的返回類型getType()

正如Adrian所建議的,使用注釋是最好的恕我直言。

暫無
暫無

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

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