2011-07-27 76 views
6

我創建了一個沒有。的常量變量,超過1000個,那些常量是唯一的整數。我可以打印出變量的名稱嗎?

public static final FOO 335343 
public static final BAR 234234 
public static final BEZ 122424 
.... 
.... 
.... 

有沒有辦法打印出FOO,BAR和BEZ,這是Java中名稱的變量? 我不熟悉java反射。我不知道這是否有幫助。

if (FOO == 335343) 
    ---> output "FOO" 
if (BAR == 234234) 
    ---> ouptut "BAR" 
.... 

其實是問這背後的問題是,我想寫登錄到文件

System.out.println("This time the output is " + FOO); 

和實際產量

This time the output is 335323 

我想知道哪個變量來自335323. 除了放置這些變量之外,還有其他方法嗎?可靠的和它的相關常量變成hashMap?

感謝

+3

爲什麼?這樣做的目標是什麼?爲什麼變量名在運行代碼中更重要?或者你真的想要使用枚舉嗎?我強烈懷疑目前問題的最佳解決方案是以完全不同的方式解決問題。所以有鑑於此,或許你最好告訴我們你試圖解決什麼問題,而不是你如何解決它。 [通過反射訪問Java靜態最終的ivar值]的 –

+0

可能重複(http://stackoverflow.com/questions/850148/accessing-java-static-final-ivar-value-through-reflection) –

+0

@Kit:請參閱編輯(標記爲編輯1)在我的答案下面。 –

回答

2

您可以使用類似:

for (Field field : MyClass.class.getDeclaredFields()){ 
    if (field.getType().toString().equals("int")){ 
     int val = (Integer)field.get(MyClass.this); 
     switch (val){ 
      case 335343: 
      case 234234: 
       System.out.println(field.getName()); 
     } 
    } 
} 

記住更改MyClass您的類名,並至少有一個實例應該存在獲取字段的值。因此,如果您計劃使用main方法測試代碼,則應將MyClass.this更改爲new Myclass()之類的內容。 要記住的另一件事是,字段是屬性而不是方法變量(所以如果你使用它來訪問方法中聲明的變量,它將不起作用)。

+0

會不會更好,更靈活? –

+0

是的(對於某些情況),但在這種情況下,當您修改類時(甚至打開類以搜索屬性),不需要記住修改地圖。無論如何,它將主要取決於你要給代碼的用途。如果該方法將被大量使用,那麼也許可以將所有字段(getDeclaredFields())的默認值添加到地圖中。 – Fido

2

正如我在對原文的評論中指出的,我強烈懷疑當前問題的最佳解決方案是以完全不同的方式解決問題。你似乎想要將一個int與一個String相關聯,並且做到這一點的一種方法是使用一個Map,比如一個HashMap。對於例如,

import java.util.HashMap; 
import java.util.Map; 

public class MapDemo { 
    public static void main(String[] args) { 
     Map<Integer, String> myMap = new HashMap<Integer, String>(); 
     myMap.put(335343, "FOO"); 
     myMap.put(234234, "BAR"); 
     myMap.put(122424, "BEZ"); 

     int[] tests = {335343, 234234, 122424, 101010}; 

     for (int i : tests) { 
     // note that null is returned if the key isn't in the map 
     System.out.printf("%d corresponds to %s%n", i, myMap.get(i)); 
     } 
    } 
} 

編輯1:
根據您最近的評論和更新到你原來的問題,我認爲你有很多數字和參與這一計劃及其相關的字符串和您的需要是找到與該號碼關聯的字符串。如果是這樣,那麼你需要考慮重新設計,數字和字符串不應該被硬編碼到你的程序中,而應該成爲程序數據的一部分,也許在一個文本文件中,一列是數字,另一列是數字列(可能由一個空格分隔),相關的文本。通過這種方式,您可以讀取數據並在HashMap,數據庫或任何您想要的方式中輕鬆使用它。這將爲您的項目提供更大的靈活性和健壯性。

+0

有可能使用哈希映射,但我已經聲明瞭很多常量變量,並且我不想將它們全部硬編碼並將其放入哈希映射中 –

+0

@Kit:您還沒有告訴我們任何關於你正在努力完成什麼。如果沒有這些信息,我不知道我們可以如何建議你。 –

+0

我已經更新了我的答案。感謝您的幫助 –

4

有一些'特殊情況',你可以有這方面的解決方法(這是由別人告知),但最重要的問題是:你爲什麼要這樣做(打印出變量名稱)?

根據我的經驗,99.9%的類似問題(如何打印變量名稱?如何獲取變量取決於用戶輸入變量名稱等)實際上是由編程初學者提出的,他們只是做出了不正確的假設和設計。他們試圖實現的目標通常可以通過更合適的設計來完成。


編輯

老實說,我仍然不認爲你正在試圖做的是要走的路,但至少我認爲下面是一個可行的答案:

它或多或少是以前的答案的組合:

(沒有嘗試編譯,但至少它給了你一個想法)

class Constants { 
    public static final int FOO = 123; 
    public static final int BAR = 456; 

    private static Map<Integer, String> constantNames = null; 


    public static String getConstantName(int constVal) { 
    if (constantNames == null) { 
     Map<Integer, String> cNames = new HashMap<Integer, String>() 
     for (Field field : MyClass.class.getDeclaredFields()){ 
     if ((field.getModifiers() & (Modifier.FINAL | Modifier.STATIC)) != 0) { 
      && int.class == field.getType()){ 
      // only record final static int fields 
      cNames.put((Integer)field.get(null), field.getName()); 
     } 
     } 
     constNames = cNames; 
    } 
    return constantNames.get(constVal); 
    } 
} 

假設你想獲得一個恆定的名字,只是做:

Constants.getConstantName(123); // return "FOO" 
+0

@Adrain:更新問題以告知目標 –

+0

它仍然不能證明您要求的內容。試想一下,如果有兩個常量具有相同的值,你會做什麼? Java如何處理這種情況?它會提出一個可行的方式來更新答案,但我仍然認爲這不是一個好的方法。 –

0

我建議你打印出的行號,而不是變量名。這應該足以確定消息來自哪裏。下面是關於如何做到這一點的詳細信息:

How can we print line numbers to the log in java

+0

不是真的!造成它用於記錄。跟蹤日誌中的每一行都是有問題的。 –

1

您可以使用enum

如果這些數字只是必須是唯一的,你可以說

public enum Yourname { 
    FOO, BAR, BEZ 
} 

,並指名Yourname.FOO和值作爲Yourname.FOO.ordinal()。您可以使用枚舉if -blocks,switch -statements。

如果您想要在問題中給出的數字,那麼如果FOO需要爲335343,則可以創建編號的枚舉。看看is-it-possible-to-assign-numeric-value-to-an-enum-in-javanumber-for-each-enum-item

0

我有一個類似的問題爲int變量的一個長長的清單,我不得不打印每個變量的名稱和它的價值(主要目標是創建一個打算在Excel文件中導入的文本文件)。

不幸的是我在Java編程很新,讓我找到了唯一的解決方案(可能是錯的)是使用兩個不同的芯片:一個String名稱,一個字符串數組和另一個int數組的對應值。

例如:

int varName01, varName02, .... 
String[] listNames = new String {"varName01", "varName02", ..... 
int[] listValues = new int {varName01, varName02, ..... 
for (int i=0; i<listValues.length;i++) 
{ 
print String.format("%s %d", listNames[i], listValues[i]); 
} 

也許這是不這樣做的正確方法,所以一些Java專家發表任何意見會更受歡迎。謝謝!

相關問題