Win a copy of Escape Velocity: Better Metrics for Agile Teams this week in the Agile and Other Processes forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Tim Cooke
  • Paul Clapham
  • Jeanne Boyarsky
Sheriffs:
  • Ron McLeod
  • Frank Carver
  • Junilu Lacar
Saloon Keepers:
  • Stephan van Hulst
  • Tim Moores
  • Tim Holloway
  • Al Hobbs
  • Carey Brown
Bartenders:
  • Piet Souris
  • Frits Walraven
  • fred rosenberger

reflection of private field in super class

 
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Situation:
The private field id (primary key of DB) ist set by the JEE container and JPA. For this reason no public setter for id shall exist.
To set the id for JUnit tests, reflection is used. To make it a little bit more complicated a class employee inherits from the super class Person. The id field exist in the Person class only.
The following code snippet from JUnit test class works:

Employee empl = new Employee();
try {
// access private field id and set a unique id otherwise set by DB through container
Person pers = new Person(); //ugly workaround, but it works, create dummy super class!
// inherited declared fields are not accessible but:
Field id = pers.getClass().getDeclaredField("id"); // get id ref from super class Person
id.setAccessible(true);
id.setLong(empl, Long.valueOf(i + 1)); // use id ref on employee!
id.setAccessible(false);
} catch (Exception e) {
//handle it
}

Questions:
1.) Though it works, it looks so weird to me, I suspect rather a bug than a feature!
2.) How to do it the clean way?
3.) Who can tell me more about this.

Any background information is welcome.

Cheers Maurice
 
author
Posts: 23928
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Maurice Le Chat wrote:
1.) Though it works, it looks so weird to me, I suspect rather a bug than a feature!



Not sure what you mean by "bug". Tools sometimes need to access private data components of instances, and reflection provides a way to do it.


Unless, you mean "bug" as in a security bug, in that you can access the private component that you should not be allowed to. Basically, the set accessible method goes through the security manager, if you are using a security manager that disallows it (such as loading from an applet), it will throw an exception.

Henry
 
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You don't need an instance of a class to get the Class object - you can use a class literal. You can delete the line creating a Person, and replace pers.getClass() with Person.class.
 
Java Cowboy
Posts: 16084
88
Android Scala IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Maurice Le Chat wrote:
Questions:
1.) Though it works, it looks so weird to me, I suspect rather a bug than a feature!
2.) How to do it the clean way?
3.) Who can tell me more about this.


You can access private members through reflection. Access specifiers such as protected and private are not meant as security measures, to make data invisible under all circumstances.

There is really no clean way to access private members from outside the class. The whole purpose of private members is to make them not accessible from outside the class. If you want to be able to change the value of a member variable cleanly, provide a setter method (which can be public) to set the value.

Accessing private member variables through reflection is a trick that some frameworks such as Hibernate use. You shouldn't normally do such things in your code yourself.
 
Maurice Le Chat
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@Matthiew
You are right of course! I didn't yet think about optimizing. I was surprised by the fact to get a handle (field object) to the private id field I want, simply going through the superclass and being able to use this reference to access the id field in a real object, being an extention of this superclass!

@Jesper @Henry
The above is the point! Please read carefully my description of the situation. The application use JPA. A couple of years ago I would have used Hibernate. Anway it's the same. I know reflection and it's use by tools. The point is:
Java SE API says clearly for getDeclaredFields() " ... This includes public, protected, default (package) access, and private fields, but excludes inherited fields." In fact calling getDeclaredField("id") on th derived class Employee throws NoSuchFieldException! So far no surprise. I wonder the fact it's so easy to circumvent this limitation by getting a field object of the superclass and later manipulating with this same object a previously created object of a derived class!
Though I use the reflection in JUnit only, I would be assured to know if this behaviour is by specification, or by accident! If the latter is true, I would like to know, how others do it, or how the tools (Hibernate, etc.) do it.

Thanks

Maurice
 
Sheriff
Posts: 22684
128
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Maurice Le Chat wrote:I wonder the fact it's so easy to circumvent this limitation by getting a field object of the superclass and later manipulating with this same object a previously created object of a derived class!


Well, have you tried? You may be surprised!
 
Maurice Le Chat
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Of course I tried! I havent seen any surprise! The main intend of this thread is to avoid future surprises by getting deeper knowledge from the community. Please explain what do you mean by surprise!
 
Montana has cold dark nights. Perfect for the heat from incandescent light. Tiny ad:
the value of filler advertising in 2021
https://coderanch.com/t/730886/filler-advertising
reply
    Bookmark Topic Watch Topic
  • New Topic