The docs (see above) state quite clearly that this is considered risky, and that it should only be allowed if you know what you are doing. However, since it breaks expectations, you should use it sparingly and make sure that users know that you require the extra permissions and "are looking under the hood". It allows java code to serialize and de-serialize objects with private fields, it allows complex mocking that may simplify testing, it allows you to peek into places you would not otherwise be able to peek into. Yes, as long as your program keeps on running the fields will remain accessible (as long as you keep on using the same Field instance where you changed access permissions). Yes - you need several JVM permissions (most notably accessDeclaredMembers and suppressAccessChecks, marked with big, bold warnings in the docs) for this to work if your JVM's security profile is somewhat strict (say, the much-maligned applets), your code will not work because these permissions will not be available. Java: Accessing private field via reflection (behaviour) This code works: Class clazz = Child.class įield f1 = cc.getClass().getSuperclass().getDeclaredField("a_field") You can pull the field off the super class. To access a private field you need to set Field::setAccessible to true. The RuntimeExceptions which may be thrown are either SecurityExceptions (if the JVM's SecurityManager will not allow you to change a field's accessibility), or IllegalArgumentExceptions, if you try and access the field on an object not of the field's class's type: f.get("BOB") //will throw IllegalArgumentException, as String is of the wrong type The IllegalAccessException would be thrown if the field was not accessible (for example, if it is private and has not been made accessible via missing out the f.setAccessible(true) line. obj.getClass().getDeclaredField("misspelled") //will throw NoSuchFieldException The NoSuchFieldException would be thrown if you asked for a field by a name which did not correspond to a declared field. Hashtable iWantThis = (Hashtable) f.get(obj) //IllegalAccessExceptionĮDIT: as has been commented by aperkins, both accessing the field, setting it as accessible and retrieving the value can throw Exceptions, although the only checked exceptions you need to be mindful of are commented above. In order to access private fields, you need to get them from the class's declared fields and then make them accessible: Field f = obj.getClass().getDeclaredField("stuffIWant") //NoSuchFieldException public abstract class AbstractTest is an inner class defined in a static context and does not have an enclosing instance.How to read the value of a private field from a different class in Java? The only way around it that I can think of is to override showFields() in TestClass, swallow any exceptions about not being able to access private fields, then call super.showFields() and swallow any exceptions again. Fields in TestClass are essentially walled off. if a method is declared protected in the abstract class and the extending class is in a different package, then it cannot be accessed (and vice versa).īecause the method showFields() is defined in AbstractTestClass, it can only access the fields in that class. Sadly, this is not true: inheritance is a closer relationship that in a normal parent-child object, but access rules must still be obeyed e.g. I believe you are making the same mistake I made when I was starting out: that the abstract class and the extending class are two piece welded together to form a single class with access to all of each others fields and methods etc.
0 Comments
Leave a Reply. |