这个问题有两个答案:
AFAIK,如果不关闭所有方法,就无法“关闭”优化。
您可以做一些可能会抑制您担心当前一代 Java 编译器的特定优化的事情。例如:
private static char[] password;
public static String dummy;
public static void clearArraySafely() {
// Overwritting array
for (int i = 0 ; i <= password.length; i++) {
password[i] = 0;
}
dummy = new String(password);
password = null;
}
JIT 编译器无法优化零分配。如果是这样,那么将使用“错误”内容创建虚拟字符串。并且由于dummy
可以通过反射访问而不破坏任何 JLS 规则,因此 JIT 无法应用转义分析来避免创建它。
但是请注意,某些未来的 JIT 编译器总是有可能......更聪明。如果你想避免这种情况,你需要确保它dummy
以某种方式影响程序的输出;例如通过打印它。
有没有什么好的类来存储字符数组的密码?
AFAIK,没有一个不会遇到同样的问题。
话虽如此,进入这个级别来保护密码是(IMO)接近偏执狂。如果某人具有从堆中无法访问的对象中窃取密码所需的访问级别,他们很可能可以通过其他方式获取密码;例如通过在操作系统级别截取字符,或者通过“调试”你的JVM。
我的偏执与调试 JVM 有关。
不幸的是,你的妄想症无济于事。
例如,您设计的用于防止有人附加调试器的方案可能会被逆向工程然后修改exe
文件所破坏。你设计的任何其他方案也可以。
如果用户控制执行程序的平台,则无法阻止他/她“调试”正在运行的程序。防止它的唯一方法是仅在您控制的平台上运行应用程序。
(顺便说一句——这不是 Java 特有的问题。它适用于所有编程语言。有些语言比其他语言更容易“破解”,但如果不道德的用户熟练且有动力,并且有时间开发“黑客”。)