在进行Java和JavaScript之间的比较时,MDN JavaScript指南说明了以下内容:
类型安全意味着,例如,您不能通过破坏Java字节码将Java整数强制转换为对象引用或访问私有内存。
当然,关于上述陈述的第一部分,当谈到键入类型安全的一般概念时,围绕语言能力提供某种检查,消除了与不兼容类型执行的操作可能存在的错误条件(即使上面的例子是天真的,考虑到在Java中你可以将原始int
包装到引用类型Integer
)。
但是,声明的第二部分究竟是什么意思呢?
Here有人谈论JVM的验证器确保一定程度的内存保护 - 其中“仲裁位模式不能用作地址。”
MDN声明的第二部分如何与类型安全相关?
答案 0 :(得分:4)
我怀疑他们的意思是你无法将任意内存地址转换为其他类型,就像在C中一样。
struct bar_s {
char foo_s[100];
}
void stuff() {
int foo = 5;
bar_s *bar = &foo;
}
请原谅我,如果语法错误,我的C生锈了。这将获取foo的内存地址,将其分配给指向bar_s结构的指针,然后可以解除大量关联的痛苦。您正在处理一个最初为int的内存区域作为bar_s。
在C中,有许多攻击向量允许您用任意信息覆盖内存,并随后执行它们。见Buffer Overflow
在java中,一旦是Integer,总是一个Integer [*]。还有一些检查所有数组的边界有助于防止缓冲区溢出。
[*]直到垃圾收集。
答案 1 :(得分:3)
这意味着在Java中,(原则上)无法绕过如何识别类型。在javascript中,可以根据表示一段数据的字节序列来推断类型。在Java中,VM可以防止出现这种情况,以确保不希望将作为Foo对象的字节序列视为Bar对象。
关于访问私有成员,这意味着你不能使一系列字节意味着与程序员意图不同的东西,以获得对非预期内容的访问。在运行时,您无法将具有私有成员foo
的{{1}}类型的对象Foo
更改为foobar
类型的对象,具有相同的成员,但{{1}公开的。
每个对象的类型都在字节代码中编码,在运行时由VM控制。