7

我有一个简单的 Apple 类从另一个简单的 Fruit 类扩展而来。

在运行时,我可以使用

Fruit fruit = new Apple();

fruit.getClass();

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

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

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

4

3 回答 3

12

您实际上是在问一个关于变量声明的问题,fruit而不是对象的实际运行时类型(Apple在这种情况下是一个)。

我认为这通常是一个坏主意:您刚刚声明了变量并告诉编译器它是 a 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一个实例变量,并使用反射查询声明的类型。
  • 对源代码做一些处理以找到变量声明
  • 对编译后的字节码进行一些处理以找到声明类型(尽管有可能激进的编译器甚至可能完全优化编译时声明,例如在意识到水果在这段代码中只能是苹果之后)

我认为所有这些都很丑陋,所以我的一般建议是“不要这样做”。

于 2012-07-07T12:54:21.070 回答
3

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

于 2012-07-07T12:55:08.573 回答
3

不,没有:至少不使用反射。反射可以在运行时为您提供有关对象的信息,以及字段、方法和类,但不能提供局部变量。如果水果是一个字段,您可以执行以下操作:

FruitBasket.class.getDeclaredField("fruit").getType();
于 2012-07-07T13:00:59.737 回答