3

我正在阅读一本名为OCA Java SE 7 Programmer I Certification Guide的书,为 Java SE 7 Programmer I 考试 ( 1Z0-803 ) 做准备。尽管作者有 12 年的 Java 编程经验,并且尽管有技术校对员,这本书还是有很多缺陷,大概是拿薪水的。

不过有一件事让我没有安全感。作者在第 168 页上说,这个说法是正确的:

如果一个方法的返回类型是int,该方法可以返回一个类型的值byte

好吧,我争论不同,需要你的帮助。以这段代码为例:

public static void main(String[] args)
{
    // This line won't compile ("possible loss of precision"):
    byte line1 = returnByte();

    // compiles:
    int line2 = returnByte();

    // compiles too, we "accept" the risk of precision loss:
    byte line3 = (byte) returnByte();
}

public static int returnByte()
{
    byte b = 1;
    return b;
}

显然,编译器不会抱怨returnByte()方法签名中的不同返回类型 int 以及我们实际上在方法实现结束时返回的内容:一个字节。该字节使用的位 (8) 比 int (32) 少,并且将被强制转换为 int 而没有精度损失的风险。但是返回的值并且将永远是一个整数!还是我错了?你会在考试中回答什么?

我不完全确定实际的返回类型是什么,因为据说书中的这个陈述是正确的。强制转换是在我们的方法实现结束时发生的,还是在分配之前发生在主方法中?

在现实世界中,只要了解隐式转换和丢失精度的风险,这个问题就无关紧要了。但由于这只是考试中可能出现的问题之一,我很想知道该问题在技术上的正确答案。

澄清!

大多数答案似乎认为我想知道是否可以将 abyte转换为 anint以及随后会发生什么。好吧,这不是问题。我在问返回的类型是什么。换句话说,作者引用的陈述是对还是错?转换为 int 是在returnByte() 方法实际返回之前还是之后发生的?如果这是真正的考试并且你会得到这个问题,你会回答什么?

请参阅我的代码片段中的第 1 行。如果作者说的是对的,那么该行将编译为返回值将是一个字节。但是它不能编译,类型提升的规则说如果我们试图将一个 int 压缩成一个字节,我们就有失去精度的风险。对我来说,这证明了返回的值是一个整数。

4

3 回答 3

1

是的,你可以这么做。

  • 表达式的值在返回之前byte将被提升。int

  • 实际的返回类型在方法签名中声明 - int

IMO,那本书的作者写的或多或少是正确的。return他只是省略了解释当你“返回一个字节”时语句中发生的字节到整数提升的一点。

强制转换是在我们的方法实现结束时发生的,还是在分配之前发生在主方法中?

演员(晋升)发生在returnByte方法中。

在现实世界中,只要了解隐式转换和丢失精度的风险,这个问题就无关紧要了。

byte将 a 提升为a 不会损失精度int。如果类型不同,则可能会损失精度,但(假设)无论在何处执行提升,精度损失都是相同的。


JLS 中处理这个问题的部分是 JLS 14.17,它说return表达式必须可分配给方法声明的返回类型。它没有明确说明提升是在方法中完成的,但它是隐含的。此外,这是实现这一点的唯一实用方法。

如果(假设)转换是在调用方法(例如main)中完成的,那么:

  • 编译器需要知道return语句在做什么。这是不可能的,因为 Java 类可以单独编译。
  • 编译器需要知道将调用哪个实际方法。如果方法被覆盖,这是不可能的。
  • 如果该方法包含两个(或更多)return具有不同类型表达式的语句,则编译器需要知道return将执行哪个语句。这是不可能的。

如果这是真正的考试并且你会得到这个问题,你会回答什么?

我会回答……“这取决于”……然后转向其他观点。

从技术上讲,该方法返回一个int,但该return语句可以采用任何类型可以转换为 的表达式int

但是,如果有人对我说该方法返回 a byte,我会理解他们的意思。


此外,据我所知,方法/函数将堆栈用于 storage.etc,并且在这些堆栈内,它们存储返回地址而不是它们返回的(类型)。因此,再次出现歧义(至少对我而言)。如果我错了,请纠正我。

是的,从技术上讲,方法不会返回类型。(即使它返回一个Type对象也不会。这是一个表示类型的对象,而不是类型本身。)但是每个人和他的狗都会高兴地说“returnByte 方法返回类型 int”。

因此,如果您要迂腐,那么是的,这是模棱两可的。但解决办法是不要学究气。

于 2013-08-17T10:48:54.377 回答
0

我相当确定它与myInt << 24获取最后八位的操作相同,因此如果整数超过 255(2^8) 的值,则精度即将损失。

于 2013-08-17T10:38:12.510 回答
0

是的,该声明是有效的。A将始终舒适地byte融入其中。int

byte => int //no precision loss
int  => byte //precision loss

但如果你正在做:

byte => int => byte //you won't lose any data

这就是你在做什么。这有帮助吗?

于 2013-08-17T10:52:17.473 回答