2

I have 3rd party data model class, where some fields and methods are private. I want hack this class to wrap these private fields to be accessible externally.

For example the data model is defaultModel.java. I want extend it to create a sub class RefineddefaultModel.java, which wraps its private field by using Java reflection.

Are there any good design patterns do this?

Because I felt only in my sub class to reflect it somehow it is not best practice.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
C.c
  • 1,905
  • 6
  • 30
  • 47
  • 14
    If you're modifying private fields with reflection, you're already in the realm of "not best practice" IMO. – Jon Skeet Oct 14 '13 at 07:25
  • 2
    I agree with Jon Skeet, if the class was designed not to be overridden or to hide some data from subclasses, the best practice would be not to hack the class. Besides that there are a lot of cases that could break your code, e.g. SecurityManagers not allowing access to those fields, changes in future versions of the base class etc. – Thomas Oct 14 '13 at 07:31
  • Maybe you could elaborate a bit on what your actual goal is. I'm sure there would be better design options in your specific case. – Thomas Oct 14 '13 at 07:33
  • I understood this is not best practice, but I have to, I wonder what is the best practice base on this – C.c Oct 14 '13 at 08:00
  • I agree with Jon & Thomas. However, you might be able to use [ASM](http://asm.ow2.org/) to modify the class itself and add getters and setters for those variables. It's what is used under the hood for several proxy libraries. – Pace Oct 14 '13 at 11:14
  • Explain your situation in code and why you need to access those private variables. Nobody can advice you without knowing the code and the goal. – Bart Oct 14 '13 at 13:34
  • http://stackoverflow.com/questions/1196192/how-do-i-read-a-private-field-in-java – Lodewijk Bogaards Oct 15 '13 at 09:25

1 Answers1

3

Are there any good design patterns do this?

NO! Messing with private fields is the root to all evil, so there is no good way. You can (and most likely will) violated class invariants and concurrency support, risk incompatibility with future versions and will end up with a lot of unexpected behaviour at runtime. The fact that you need to, is a sign that something is seriously wrong with you design or how you use libraries.


If you asked: Is it possible in a horrible way? the answer is yes. You can do something like this.

// Possible but horrible:
Field field = object.getClass().getDeclaredField("privateField");
field.setAccessible(true);
oldValue = field.get(object);
field.set(object, newValue);

If you want things not to get completely out of hand only do gets and never do sets. I would further avoid extending the object and messing with the class structure. You can use the Adapter pattern using composition for this.

If any of the fields are final you might get additional problems. See this existing question: Changing private final fields via reflection. You can also see How do I read a private field in Java?

But I must stress this: Try hard to avoid this and make your future self happy. :)

Community
  • 1
  • 1
Tobber
  • 7,211
  • 8
  • 33
  • 56