Reputation: 871
I am attempting to access a private member from another class in Java. Is this a possible task? Currently there is no getter method for this member.
Below is an image of what I would like to obtain;
Upvotes: 2
Views: 11427
Reputation: 64012
You can extend classes that are with in .jar and even without sources using AspectJ (Java version of Aspect Oriented Programming) http://www.eclipse.org/aspectj/
For your example you can modify standard ArrayList behavior, e.g. copy information aside when addition is called.
This is however not Java language and requires some learning, e.g. what is advice.
Note: AspectJ is heavily used internally in Spring framework.
Upvotes: 0
Reputation: 8932
You can't do it direct. The Java Language Specification is quite clear about this (see chapter Controlling Access to Members of a Class). A "private" member is only accessible from class it is defined, and neither from classes in the same package nor from subclasses (but from a nested class, see Java Language Specification, chapter Determining Accessibility).
You can circumvent this using reflection. For this you have to get the class, then find the description of the filed. With the description of the filed, you can then set the value for this field.
Example (from the Java tutorial):
Class<?> c = book.getClass();
Field chap = c.getDeclaredField("chapters");
// Reading the value
Object value = chap.getLong(book);
// Writing the value
// Here you might have to insert the code below
chap.setLong(book, 12);
If you only want to read, you are done (the Java securoty manager might still prevent you from reading the field). If you also want to write the field, things become more complicated. And this might even bring you to read a wrong value (in a very theoretical corner case, but still). See below for more details.
This will not work under all conditions. For final fields you have to make them accessible, and for private final fields, you have to additionally change the modifier, before you can set the value (an example can be found here):
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
Additionally the Java security manager might prevent you from doing this.
When the compiler has already inlined the filed, this technique will have no effect. Then the compiler has changed your program during compile time: it exchanged each reference to the filed with the value. Datails can be found in the Java Language Specification (chapter Subsequent Modification of Final Field):
In some cases, such as deserialization, the system will need to change the final fields of an object after construction. final fields can be changed via reflection and other implementation dependent means. The only pattern in which this has reasonable semantics is one in which an object is constructed and then the final fields of the object are updated. The object should not be made visible to other threads, nor should the final fields be read, until all updates to the final fields of the object are complete. Freezes of a final field occur both at the end of the constructor in which the final field is set, and immediately after each modification of a final field via reflection or other special mechanism.
Even then, there are a number of complications. If a final field is initialized to a compile-time constant in the field declaration, changes to the final field may not be observed, since uses of that final field are replaced at compile time with the compile-time constant.
Another problem is that the specification allows aggressive optimization of final fields. Within a thread, it is permissible to reorder reads of a final field with those modifications of a final field that do not take place in the constructor.
Because of this, you might read a wrong value with the code above. If someone changed a field using reflection, and you read the value back later, you will not read the value the actual code is using. So you will read a wrong value in this case:
private final static
fieldUpvotes: 1
Reputation: 2959
private
This keyword in itself says that the variable or a method or a function associated with it, is no longer available to the class's object. To access it, you need to make a public method in which you will use it.
Upvotes: -1
Reputation: 25874
If one member is private, it's for a good reason: data encapsulation. This is basic object-oriented philosophy: that member is not meant to be accessed, which means this information is only relevant to this class and should not be relevant to any other class.
If you can modify this class, you can add a getter for this field, but make sure this is really what you want. As I said above, if it's private and has no getters, it's for a reason.
If this class is from an external library or framework, then you're most likely using it wrong. If you still want to access this private field, you can use reflection to access it (you can do this in several different ways, but I think what you're looking for is Topolnik's answer).
Upvotes: 2
Reputation: 11658
You can do it with Reflection
but do it on your own risk as it's not recommended.
Below is an Example for your given situation:
YOURCLASS f = new YOURCLASS(); //Make an object of your class
Field a = f.getClass().getDeclaredField("privateListObject"); //get private declared object from class
a.setAccessible(true); //Make it accessible so you can access it
ArrayList al = (ArrayList) a.get(f); // At last it's yours.
Upvotes: 1
Reputation: 191
It is possible using reflection, see this link for a good explanation of how. How do I read a private field in Java?
That said, you really really need to have an extremely good reason for doing so, because if you don't control the code chances are that sometime down the road the owner of that code makes a change and everything breaks at runtime. And if you own the code there is no reason to do it in the first place.
If you control the code or have access to the owner, do the right thing and implement proper access methods to get the data you need.
Upvotes: 6
Reputation: 8255
You can't, unless you use reflection (more about that below).
If the member is declared private
, then other classes aren't allowed to read it. That's what private scope is about.
If you can modify the class that owns the ArrayList, you can add a getter. It is better not to get the ArrayList in it's entirety (it's a reference and you might inadvertently change it). Add a getter that gets one element, instead.
There is also the option to use reflection, but as is mentioned several times on this page, this is strongly discouraged. Reflection is a technology that allows code to inspect other code in the same system. Should you really want to use it, the tutorial is here.
Upvotes: 5
Reputation: 200296
This is how it is done using reflection:
java.lang.reflect.*
instance reflecting your member of interest, starting from obj.getClass()
;member.setAccessible(true)
;The usual warning is that this must not be a part of your overall design, but if there is a good reason why you need it, there it is.
Upvotes: 3
Reputation: 38228
Is it for testing ? If yes I think you can use reflection, otherwise it is not recommanded.
Upvotes: 0
Reputation: 191
You can access private variables only from methods of the same class.. So you must create a getter method to return that array
Upvotes: -3