如何在Java中找出声明的标识符类型?

时间:2012-07-07 12:42:38

标签: java class reflection runtime polymorphism

我有一个简单的类Apple扩展自另一个简单的类Fruit。

在运行时,我可以使用

Fruit fruit = new Apple();

fruit.getClass();

获取实际类型的水果对象,即Apple.class。

我还可以使用fruit instanceof Applefruit instanceof Fruit来验证此水果对象是Apple还是Fruit的实例。这两个表达式都返回true,这是正常的。

但有没有办法确定fruit标识符的声明类型?在这种情况下,Fruit

3 个答案:

答案 0 :(得分: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之后)

我认为所有这些都非常难看,所以我的一般建议是“不要这样做”。

答案 1 :(得分:3)

Fruit对象没有声明的类型。它的类型是变量 fruit。由于您可以传递的唯一内容是对Fruit对象的引用,因此我认为您的请求没有多大意义。你可以得到的最好的是你有一个存储对象的特定实例变量。然后,您可以反映该字段并使用Field.getType()获取其声明的类型。

答案 2 :(得分:3)

不,没有:至少不使用反射。 Reflection可以在运行时为您提供有关对象的信息,以及字段,方法和类,但不提供局部变量。如果水果是田地,你可以做以下事情:

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