2012-07-07 63 views
6

我有一個簡單的類蘋果延伸從另一個簡單的類水果。如何找出Java中標識符的聲明類型?

在運行時,我可以用

Fruit fruit = new Apple(); 

fruit.getClass(); 

獲得實際類型的水果對象,這是Apple.class的。

我也可以使用fruit instanceof Applefruit instanceof Fruit來驗證這個水果對象是Apple還是Fruit的一個實例。這兩個表達式都返回true,這是正常的。

但是有沒有一種方法可以精確確定標識符的聲明類型?在這種情況下是Fruit

+1

你應該描述你想在達到差異化後達到什麼效果。我相信還有其他方法可以解決這個原始問題。 – Bananeweizen 2012-07-07 12:56:58

+2

我很好奇爲什麼你想知道(如何聲明'水果'),以及分開,爲什麼你不知道*因爲你有代碼在你面前。我沒有提出一個用例。 'fruit'指向**的對象是** Apple'。你通過'fruit'變量的接口是'Fruit',但這純粹是編譯時的事情。 – 2012-07-07 12:58:00

+0

這樣做的意義是什麼 - 你已經將水果編碼爲水果,所以你已經知道它就是這樣。 – DaveRlz 2012-07-07 12:59:37

回答

9

實際上,您正在詢問有關fruit的變量聲明的問題,而不是對象的實際運行時類型(在本例中爲Apple)。

我覺得這是一般一個壞主意:你剛纔聲明的變量,並告訴編譯器,這是一個Fruit,那麼爲什麼你需要現在需要找出這方面的?

僅僅是用來迷惑的問題,甚至更多,這是值得注意的是,你還可以有不同的聲明類型引用相同的對象(這仍然是一個Apple)的多個變量:

Fruit fruit = new Apple(); // fruit declared as Fruit, but refers to an Apple 
Object thing = fruit;  // thing declared as Object, refers to the same Apple 

如果你真的想找到從聲明的類型,那麼你有幾種選擇:

  • fruit一個實例變量,並使用反射查詢聲明的類型。
  • 對源代碼進行一些處理以查找變量聲明
  • 對已編譯的字節碼進行一些處理以查找聲明類型(儘管積極的編譯器可能甚至會優化編譯時聲明,例如在意識到水果只能是此代碼中的Apple)

我認爲所有這些都很醜,所以我的一般建議是「不要這樣做」。

+2

的確不好。值得一提的是變量是一個編譯時間實體。如果編譯器優化它,它在運行時可能根本不存在。 – eran 2012-07-07 12:57:08

+0

謝謝@mikera,我認爲你是對的。我的問題沒有多大意義。我想知道如果我可以得到對象的實際運行時類型,我也可以獲得引用此對象的聲明變量的類型。但謝謝你:) – 2012-07-08 09:15:50

3

Fruit對象沒有聲明類型。它的類型爲變量fruit。由於您唯一可以傳遞的是對Fruit對象的引用,因此我認爲您的請求不合理。你可以得到最好的結果是如果你有一個特定的實例變量存儲你的對象。然後,您可以反思該領域,並獲得Field.getType()的聲明類型。

3

不,不存在:至少不使用反射。反射可以在運行時爲您提供有關對象的信息,以及字段,方法和類,但不是本地變量。如果水果是一個領域,你可以做類似如下的事情:

FruitBasket.class.getDeclaredField("fruit").getType();