我想知道实际使用的不安全性sun.misc.Unsafe.我想创建一个对象的代理,我拦截每个方法调用(但Object.finalize出于性能考虑而去的那个).为此,我用谷歌搜索了一下,并提出了以下代码片段:
class MyClass {
private final String value;
MyClass() {
this.value = "called";
}
public void print() {
System.out.println(value);
}
}
@org.junit.Test
public void testConstructorTrespassing() throws Exception {
@SuppressWarnings("unchecked")
Constructor<MyClass> constructor = ReflectionFactory.getReflectionFactory()
.newConstructorForSerialization(MyClass.class, Object.class.getConstructor());
constructor.setAccessible(true);
assertNull(constructor.newInstance().print());
}
Run Code Online (Sandbox Code Playgroud)
我的考虑是:
sun.misc.Unsafe被认为是Java 9中公共API的一部分sun.misc.Unsafe从那时起,许多非Oracle虚拟机也会提供- 我猜 - 有很多库已经使用它了.这也使得这个班级不太可能消失我仍然想知道:还有其他原因我不应该使用sun.misc.Unsafe我没有想到的吗?如果你谷歌这个问题,人们宁愿回答一个未指定,因为它不安全,但我真的不觉得除了(非常不可能)该方法将有一天从Oracle VM消失的可能性.
我实际上需要创建一个对象而不需要调用构造函数来克服Java的类型系统.我不考虑sun.misc.Unsafe对性能的原因.
附加信息:我ReflectionFactory在示例中使用的是方便的,Unsafe最终委托给了.我知道像objenesis这样的库,但看看我发现的代码,他们基本上做了类似的事情,但在使用Java版本时检查其他方法,这对我来说无论如何也是如此,所以我想写四行是值得保存依赖.
有三个重要(IMO)问题:
Unsafe该类中的方法具有违反运行时类型安全性的能力,并且可以执行其他可能导致JVM"硬崩溃"的事情.
实际上,使用Unsafe做的任何事情在理论上都可能依赖于JVM的内部细节; 即JVM如何处理和表示事物的细节.这些可能与平台有关,可能会从一个版本的Java更改为下一个版本.
您正在使用的方法......甚至是类名本身......在不同版本,平台和供应商之间可能不一样.
国际海事组织,这些有充分理由不这样做......但这是一个意见问题.
现在,如果Unsafe成为标准化/标准Java API的一部分(例如在Java 9中),那么上述一些问题就没有实际意义了.但我认为,如果你犯了错误,硬崩溃的风险将永远存在.
| 归档时间: |
|
| 查看次数: |
2148 次 |
| 最近记录: |