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

2022-01-24 00:00:00 class runtime polymorphism reflection java

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

I have a simple class Apple extends from another simple class Fruit.

在运行时,我可以使用

At run-time, I could use

Fruit fruit = new Apple();

fruit.getClass();

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

to get the actual type of fruit object, which is Apple.class.

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

I could also use fruit instanceof Apple, and fruit instanceof Fruit to verify if this fruit object is an instance of Apple or Fruit. Both of these 2 expressions return true, which is normal.

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

But is there a way to determine precisely the declared type of fruit identifier? Which in this case is Fruit.

推荐答案

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

You're actually asking a question about the variable declaration of fruit rather than the actual runtime type of the object (which is an Apple in this case).

我认为这通常是一个坏主意:你刚刚声明了变量并告诉编译器它是一个Fruit,那么为什么你现在需要找出这个呢?

I think this is in general a bad idea: you just declared the variable and told the compiler that it is a Fruit, so why do you need to now need to find this out?

为了让事情更加混乱,值得注意的是,您还可以有多个具有不同声明类型的变量引用同一个对象(仍然是 Apple):

Just to confuse matters even more, it's worth noting that you can also have multiple variables with different declared types referencing the same object (which is still an 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

如果你真的想找出声明的类型,那么你有几个选择:

If you really want to find out the declared type, then you have a few options:

  • fruit设为实例变量,并使用反射查询声明的类型.
  • 对源代码进行一些处理以找到变量声明
  • 对编译后的字节码进行一些处理以找到声明类型(尽管激进的编译器甚至可能完全优化编译时声明,例如在意识到水果在这段代码中只能是苹果之后)
  • Make fruit an instance variable, and query the declared type using reflection.
  • Do some processing of the source code to find the variable declaration
  • Do some processing of the compiled bytecode to find the declaration type (although there is a possibility that an aggressive compiler might even optimise the compile time declaration away altogether, e.g. after realising that fruit can only ever be an Apple in this code)

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

I think all of these are pretty ugly, so my general advice would be "don't do it".

相关文章