Java 中原始类型的子类型化

问题描述

我在大学课堂上关于子类型关系的笔记中有这样的声明:

如果为类型 S 的变量编写的代码也可以安全地用于类型 T 的变量,则 T 是 S 的子类型

Java Language Spec 的第 4.10.1 节描述了 Java 中原始类型之间的子类型关系。特别是,根据 JLS,我使用 int <: longintlong 的子类型这一事实。

因此,如果 intlong 的子类型,那么为 long 类型的变量编写的代码也可以安全地用于 int 类型的变量。

这对我来说没有意义,如果我有一段像

long x = 2e63 - 1

然后通过上面的语句,我可以使用

int x = 2e63 - 1

这显然会导致溢出。

在我看来,语句的第二部分应该颠倒过来,即“如果为 T 类型的变量编写的代码可以安全地用于 S 类型的变量,则 T 是 S 的子类型”。但是,在我寻找答案的过程中,似乎在其他地方的其他班级笔记中重复了这一陈述。我只是误解了吗?也许我给出的例子不是该语句的有效案例?

解决方法

因此,如果 intlong 的子类型,那么为 long 类型的变量编写的代码也可以安全地用于 int 类型的变量。

好的……我可以看出这是子类型的有效表征。

然而,这并不是 JLS 实际指定和使用子类型关系 <: 的方式。在 JLS 中,子类型主要是关于的使用方式。

因此,例如,int <: longintlong 的子类型)意味着 int 值可以在需要 {{1 }} 值。

以下是一些示例:

long

请注意,在上面的每一个中,JLS 都说原始扩展转换用于将 int i = 1; long l = i; // OK - int used where a long is needed long ll = i + 1L; // OK - int used where a long is needed public void methodWithLongArg(long arg) { ... } methodWithLongArg(i); // OK - int used where a long is needed 值转换为 int 值。

那么你的例子呢:

long

事实上, 两者都不是合法的 Java。文字 long x = 2e63 - 1; // NOT OK int i = 2e63 - 1; // NOT OK 实际上是一个(双)浮点文字。 (所有使用 2e63e 表示法的文字都是浮点数,无论文字中是否有明确的小数点。没有 E 或 {{1} 的浮点文字} 后缀表示 f 值。)所以 F 的计算结果为 double,而 2e63 - 1 不能分配给 double(或 double)除非你明确地投射它。

这与子类型一致。 JLS 规则意味着 long。所以这意味着可以在需要 int 的上下文中使用 long <: double。但是在上面,我们需要在需要 long(或 double)的上下文中使用 double。这与子类型关系所允许的相反

其实你的例子还有一个问题。 263 写成(十进制)为 long。并且只有在它前面有一个一元减号运算符时才能使用它。同样,它也不能表示为 Java 二进制、八进制或十六进制文字语法中的 int 文字。


我认为真正的问题是你误解了你的讲师所说的话。

实际上说的是,为超类型编写的代码可以应用于子类型的值。

因此,在我的示例中,9223372036854775808L 方法是为超类型编写的代码;即long。它可以在子类型的值上使用(调用);即 methodWithLongArg(long arg) 变量的值。

我只是误会了吗?也许我给出的例子不是该语句的有效案例?

基本上,是的。海事组织。

,

我不认为 intlongdouble 的真正子类型。它们只是相同的整数数据类型,但每个都有不同的关键字和不同的长度。声明 int <: longlong <: double 是必需的,以便知道这些数据类型可以无损转换到一个方向

Java byte-code 展示了如何在幕后处理这些原始数据类型。通常 longdouble 只不过是语言结构,因为 int 是使用的数据类型:

请注意,根据 Java 指令集,any 引用的“值”指的是 32 位 int

例如:从 int 转换到 long 完全没有问题,但是当从 long 转换到 int 时,二进制表示可能会超过可用的数字正确表达价值;如果给定的值太大,则需要两个 int 来表示一个 long 变量(通过二进制补码将它们加在一起不会产生相同的值,因为它必须是分成两组位)。看看它们的二进制表示……那些应该使主题显而易见。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...