4

只是想知道,为什么发明 Java 的人会编写类似 的方法setAccessible(boolean flag),这使得访问修饰符(特别是私有的)无用并且无法保护字段、方法和构造函数不被访问?看下面这个简单的例子:

public class BankAccount
{
    private double balance = 100.0;

    public boolean withdrawCash(double cash)
    {
        if(cash <= balance)
        {
            balance -= cash;
            System.out.println("You have withdrawn " + cash + " dollars! The new balance is: " + balance);
            return true;
        }
        else System.out.println("Sorry, your balance (" + balance + ") is less than what you have requested (" + cash + ")!");
        return false;
    }
}

import java.lang.reflect.Field;

public class Test
{
    public static void main(String[] args) throws Exception
    {
        BankAccount myAccount = new BankAccount();
        myAccount.withdrawCash(150);

        Field f = BankAccount.class.getDeclaredFields()[0];
        f.setAccessible(true);
        f.set(myAccount, 1000000); // I am a millionaire now ;)

        myAccount.withdrawCash(500000);
    }
}

输出:

Sorry, your balance (100.0) is less than what you have requested
(150.0)! You have withdrawn 500000.0 dollars! The new balance is: 500000.0
4

2 回答 2

6

因为某些代码是受信任的代码——即,如果本地应用程序想要这样做,也许这没什么大不了的。但是,对于不受信任的代码——例如,applet,或 web 启动应用程序,或 RMI 存根,或任何其他下载的代码——有一个适当的SecurityManager位置,它(通常基于策略文件)有机会说“对不起,查理”并拒绝该setAccessible()请求。

于 2012-09-02T16:20:20.397 回答
2

Well, once you have released a Java program, anyone is free to reverse engineer, or de-compile, it anyways, so if someone wanted it badly enough, they would probably be able to access your your "privates" anyway.

What you can do however, is to forbid any foreign code to access your stuff in your runtime. That is, if you're for instance using someone else's code you could disable reflections, access to files etc before those libraries are used.

Search for ClassLoader and Security Manager to find out more. Here's something that looks relevant.

于 2012-09-02T16:24:52.020 回答