为何Y.class.getField("name")返回B.name而非A.name?Java规范有相关说明吗?
Y.class.getField("name") return B.name instead of A.name? Great question! The key here lies in the specific lookup order that Java's reflection API uses for public fields, which prioritizes directly implemented interfaces before checking the class's parent hierarchy. Let's break this down step by step.
First, let's recap your code structure to ground the explanation:
- Interface
Adefines a public staticnamefield - Interface
Balso defines a public staticnamefield - Class
XimplementsA(but doesn't declare its ownnamefield) - Class
YextendsXand directly implementsB
When you call Y.class.getField("name"), here's exactly what happens, per Java's official rules for the Class.getField(String) method:
- Check the class itself:
Ydoesn't declare anamefield, so we move to the next step. - Check directly implemented interfaces (in declaration order): Java first looks at the interfaces
Yexplicitly declares it implements—first up isB. SinceBhas a matching public staticnamefield, the lookup stops immediately and returnsB.name. - Check parent class hierarchy: This step never gets reached because we found a matching field in step 2. Even though
Yinherits fromX(which implementsA), the interface lookup takes priority over checking the parent class and its inherited interfaces.
To put this in official terms, here's the core rule from Java's reflection specification:
When looking for a public field via
getField(), the lookup follows this priority:
- First, check the class itself for a matching public field.
- If not found, recursively check each direct superinterface of the class (in the order they were declared), including the interfaces' own superinterfaces.
- If still not found, recursively check the class's direct superclass and its entire inheritance hierarchy.
- If no matching field is found anywhere, throw a
NoSuchFieldException.
It's also worth noting that Java doesn't actually "inherit" static interface fields into implementing classes—these fields belong strictly to the interface itself. But the reflection API includes them in the lookup process for classes that implement the interface, which is why Y.class.getField("name") can find B.name at all.
内容的提问来源于stack exchange,提问作者speed9

