Java和类型安全

3
MDN JavaScript指南在比较Java和JavaScript时表示如下:
类型安全意味着,例如您不能将Java整数强制转换为对象引用或通过破坏Java字节码访问私有内存。
关于上述语句的第一部分,当谈论类型时,类型安全的概念通常涉及语言提供某种检查的能力,以消除使用不兼容类型执行的操作可能出现的错误条件(尽管上面的示例很幼稚,考虑到在Java中,您可以将原始int装箱为引用类型Integer)。
但是,他们在上述声明的第二部分究竟意味着什么?
这里(此处)讨论了JVM的验证器确保了一定的内存保护级别,其中“任意位模式不能用作地址”。
MDN声明的第二部分与类型安全有何关系?

将“int”转换为引用类型“Integer”,这只是编译器的“魔法”。在内部(字节码、jni)这些类型根本不兼容。 - bestsss
2个回答

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中,有许多攻击向量允许您使用任意信息覆盖内存,并随后执行它们。请参见缓冲区溢出

在Java中,一旦是Integer,就永远是Integer[*]。所有数组都有边界检查,可帮助防止缓冲区溢出。

[*] 直到垃圾回收。


3
这意味着在Java中,(原则上)无法绕过类型标识的方式。在javascript中,可以根据表示数据的字节序列推断出类型。在Java中,虚拟机防止这种情况发生,以确保一个被设计为Foo对象的字节序列不能被视为Bar对象。
关于访问私有成员,这意味着你不能使一系列字节意味着与程序员意图不同的东西,以获取未经授权的访问权。在运行时,你不能将类型为Foo、具有私有成员foobar的对象foo更改为类型相同但具有公共foobar成员的Bar对象。每个对象的类型都编码在字节码中,由虚拟机在运行时控制。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接