views:

565

answers:

7

Consider this example :

import java.lang.reflect.Field;

public class Test {

    public static void main(String[] args) {
     C c = new C();
     try {
      Field f = C.class.getDeclaredField("a");
      f.setAccessible(true);
      Integer i = (Integer)f.get(c);
      System.out.println(i);
     } catch (Exception e) {}
    }

}

class C {
    private Integer a =6;
}

It seems illogical that you are allowed to access private fields of classes with reflection. Why is such a functionality available? Isn't it "dangerous" to allow such access?

+6  A: 

Reflection is dangerous. Period.

What's the point in limiting the utility of a really dangerous system for the sake of ever so slightly increased safety?

Also, automated serialization requires the ability to "suck the brains" out of any class; ignoring access modifiers is a necessity in this case.

Kevin Montrose
+2  A: 

From: http://java.sun.com/docs/books/tutorial/reflect/

Reflection is commonly used by programs which require the ability to examine or modify the runtime behavior of applications running in the Java virtual machine.

It's a tool that lets one break some rules, one can throw it over his foot or use it properly.

Alberto Zaccagni
+2  A: 

From the description of the java.lang.reflect package:

Classes in this package, along with java.lang.Class accommodate applications such as debuggers, interpreters, object inspectors, class browsers, and services such as Object Serialization and JavaBeans that need access to either the public members of a target object (based on its runtime class) or the members declared by a given class.

Reflection provides a mechanism for accessing information about classes through means which are usually not available by regular interaction between classes and objects. One of such is allowing access to private fields from outside classes and objects.

Yes, reflection in general can indeed be dangerous, as it can expose the internals of classes and objects.

However, it also is a very powerful tool that can be used to inspect the internals of classes and objects, which can't be accessed by other standard means.

coobird
+3  A: 

Yes it's not nice but it does allow frameworks such as Java Serialization to work.

Setting the accessible flag in a reflected object permits sophisticated applications with sufficient privilege, such as Java Object Serialization or other persistence mechanisms, to manipulate objects in a manner that would normally be prohibited.

I beleive that the functionality can be disabled through the SecurityManager

http://javabeans.asia/2008/10/12/how_to_set_securitymanager_and_java_security_policy_programmatically.html

pjp
+5  A: 

Both getDeclaredField() and setAccessible() are actually checked by the security manager and will throw an exception when your code is not allowed to do this. More often than not you won't notice it, because Java code is often run without a security manager.

One important exception are Applets, which always run with a security manager.

Joachim Sauer
You say that "Java code is often run without a security manager". There isn't a default security manager?
Firstthumb
+1  A: 
Nelson
+8  A: 

Private is intended to prevent accidental misuse, not as a security mechanism. If you choose to bypass it then you can do so at your own risk and the assumption you know what you are doing.

John Burton
+1 for "for scoping, not for security".
skaffman
+1 perfectly right private is a hint for other programmers that they should not care about the member to keep the class running. It gives you the ability to sort your code into some contracts and have the compiler check the contract that you don't directly write or read those members. But if you have to break the contract you can do it because a programming language shouldn't stand in the way of a programmer, even if he wants to shoot himself in the knee.
Janusz