3

Junior in Java; using reflection is possible to access private fields (not asking how, Question 1 and Question 2) Ok.

My questions are related with the nature of this behaviour.

  1. Is there any limitation? Can I access any field of any .class I come across?
  2. During my code, once you set the visibility of a field to lets say "public", is it changed forever or just up to the end of the context (method, if, for...)? Code below
  3. Is it ok for everybody? I mean, Seniors programmers of StackOverflow, is it a security breach?

Code [EDITED]:

  Field f = obj.getClass().getDeclaredField("field"); 
  if (...) {
     f.setAccessible(true);
     // f IS accesible
  }
  // is f accesible?
Community
  • 1
  • 1
Manu Artero
  • 9,238
  • 6
  • 58
  • 73
  • 1
    There are some situations where reflection is a breach. One situation that comes to mind is creating multiple instances of a `Singleton` class by accessing it's `private` constructor through reflection. – Chetan Kinger Apr 29 '15 at 15:10
  • 3
    What do you mean by "*During my code, once you set the visibility of a field to lets say "public",*"? If you are referring to `f.setAccessible(true)` then you are granting access to this specific instance of `Field` to field it represents. If you create another instance of `Filed` which will refer to same field (regardless of `setAccessible(true)` was invoked on previous Field instance) this new instance will not have access to private field. – Pshemo Apr 29 '15 at 15:14
  • @Chetan Kinger Exactly! If something is designed as private... Let it be private. In the case of a private attribute... try to call the realted getter. Pshemo, at the end of the context you call setAccessible is it still accessible (editing my question) – Manu Artero Apr 29 '15 at 15:22
  • 1
    @manutero Such a limitation will have to be enforced by the developer of the class. In case of the `Singleton` example, this can be done by throwing an exception in the constructor if the self reference to the instance of the class is not null. When the caller using reflection get's this exception, it should infer that the class is a Singleton and look for other ways to get a handle to an instance of the class. – Chetan Kinger Apr 29 '15 at 15:25
  • 1
    Sometimes it is desired to be able to set some private values directly, not via setters, for instance when we test our code for incorrect values (which normally couldn't be set via well written setter). – Pshemo Apr 29 '15 at 15:25

1 Answers1

3

Is there any limitation?

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.

Does it get changed forever?

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).

Is it bad?

Not necessarily. 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. 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". 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.

tucuxi
  • 17,561
  • 2
  • 43
  • 74
  • "*Does it get changed forever? Yes, as long as your program keeps on running the fields will remain accessible.*" this applies only for accessing this field by instance of `Field` on which `setAccessible(true)` was called (and there was no `SecurityException` thrown). We still will not be able to access private field directly (without reflection). – Pshemo Apr 29 '15 at 15:26