This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
I was just trying to show someone something using reflection to make my point and I've run into a snag. I wanted to list all of the fields contained by a class - that would include the fields declared within that class and the fields inherited by that class. This is what I wrote:
Obviously, I'm only getting the public fields contained by Child. Certainly, that's exactly what the API Spec says it does, but it's not what I'm after. Instead, I really want all fields contained by Child - that should include one, two, four, five, and six. I've also looked at using getDeclaredFields(), but that only returns the fields declared within Child and skips those that are inherited from Parent. Is there any way to get that information? Thanks, Corey
I don't think you can call just one method to get this list. You have to call getDeclaredFields() to get the ones in the given class, and then call theClass.getSuperClass() and call getDeclaredFields() again, and so on; you'd also want to call getInterfaces() and use getFields() on those, as well.
Hmmm... The problem is that I was trying to prove a point about inheritance. I wanted to prove that private variables are not inherited and I though reflection might be a nice way to demonstrate that. Certainly, I can get the declared fields in the subclass and the superclass, but that doesn't really show me what was and was not inherited.
But private fields are of course inherited - only the access is restricted to the parent class. Think about Person.name and Employee->Person. Of course an Employee needs the person - attributes. Else inheritance wouldn't be of much sense at all. See that often all attributes are private, and methods to handle them public.
This really depends what is meant by "inherited". JLS2 6.4.2 provides a clear, unambiguous definition, and according to it, private members are not inherited, period. Now if a private variable has a public accessor, that still works from a subclass, and from this we may infer that the data in a private field is still being stored in the JVM somewhere. Also it's possible to get at the info in the private field using reflection, or if the class is Serializable you can write it to a file and see that the file contains data from private superclass fields. However these fields are still not considered accessible in the sense that you can access them by simply wrting the name of the field like you can for most other fields. When the JLS talks about inheritance, they mean things that you can get at easily as part of the normal language functions.
This argument has been had, and Jim Yingst is right - the eventual conclusion is that the definition of "inherited" must be clearly defined before that can be said (despite what the JLS says). The following code demonstrates the concept: