如果Java方法的返回类型是int,那么该方法是否可以返回byte类型的值?

时间:2013-08-17 10:31:57

标签: java methods return-value return-type

通过阅读一本名为1Z0-803的书,我正在为Java SE 7程序员I考试(OCA Java SE 7 Programmer I Certification Guide)做准备。尽管作者在Java编程方面有12年的经验,并且尽管有技术校对员,但可能是薪水,但本书中存在大量的缺陷。

但有一件事让我感到不安全。作者在第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,以及我们在方法实现结束时实际返回的内容:一个字节。该字节比int(32)使用更少的位(8),并且将被转换为int而不存在精度损失的风险。但返回值 总是整数!还是我错了?你在考试中会得到什么回答?

我不完全确定实际的返回类型是什么,因为书中的这句话被认为是真的。 是否在我们的方法实现结束时发生了强制转换,或者在赋值之前是否在主方法中发生了强制转换?

在现实世界中,只要人们理解隐式演员和失去精确度的风险,这个问题就不重要了。但由于这只是考试中可能出现的问题之一,我很想知道问题的技术上正确答案。

澄清!

大多数答案似乎都认为我想知道是否可以将byte投射到int然后会发生什么。嗯,这不是问题。我问的是返回的类型是什么。换句话说,作者引用的陈述是对还是错?在返回的实际返回的之前或之后是否发生了对int的强制转换?如果这是真正的考试,你会有问题,你会回答什么?

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

3 个答案:

答案 0 :(得分:1)

是的,你可以这样做。

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

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

IMO,这本书的作者写的或多或少是正确的。当你“返回一个字节”时,他只是在解释有关return语句中发生的字节到整数提升的内容。

  

是否在我们的方法实现结束时发生了强制转换,或者在赋值之前是否在主方法中发生了强制转换?

演员(推广)发生在returnByte方法中。

  

在现实世界中,只要理解隐式演员和失去精确度的风险,这个问题就不重要了。

byte推广到int并不会有任何精确度。如果类型不同,可能会失去精确度,但(假设)精确度的损失在推广执行的任何地方都是相同的。


处理此问题的JLS部分是JLS 14.17,它表示return表达式必须可赋值到方法声明的返回类型。它没有明确声明促销是在方法中完成的,但它是隐含的。此外,这是实现这一目标的唯一可行方法。

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

  • 编译器需要知道return语句正在做什么。鉴于可以单独编译Java类,这是不可能的。
  • 编译器需要知道将要调用哪个实际方法。如果重写该方法,则无法执行此操作。
  • 如果方法包含两个(或多个)return语句,其表达式具有不同的类型,则编译器需要知道将执行哪个return。这是不可能的。

  

如果这是真正的考试,你会有问题,你会回答什么?

我会回答......“这取决于......”并继续进行另类观点。

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

但如果有人对我说这个方法正在返回byte,我会理解他们的意思。


  

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

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

所以,如果你要迂腐,那么是的,它是模棱两可的。但解决方案是不要迂腐。

答案 1 :(得分:0)

我相当肯定它与执行myInt << 24相同,获得最后8位,因此如果整数超过255(2 ^ 8),则即将失去精度)。

答案 2 :(得分:0)

是的,该声明是有效的。 byte将永远适合int

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

但如果你这样做:

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

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