Frage

I'm preparing myself for the Java SE 7 Programmer I exam (1Z0-803) by reading a book called OCA Java SE 7 Programmer I Certification Guide. This book has a numerous amount of flaws in it despite the author having 12 years of experience with Java programming and despite a technical proofreader, presumably on a salary.

There is one thing though that makes me insecure. The author says on page 168 that this statement is true:

If the return type of a method is int, the method can return a value of type byte.

Well I argue differently and need your help. Take this piece of code for an example:

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;
}

Obviously, the compiler do not complain about a different return type int in the returnByte() method signature and what we actually do return at the end of the method implementation: a byte. The byte uses fewer bits (8) than the int (32) and will be cast to an int without the risk of a precision loss. But the returned value is and will always be an integer! Or am I wrong? What would you have answered on the exam?

I'm not totally sure what the actual return type is, since this statement in the book is said to be true. Is the cast happening at the end of our method implementation or is the cast happening back in the main method just before assignment?

In the real world, this question would not matter as long as one understand the implicit casting and the risk of losing precision. But since this is just one of those questions that might popup on the exam, I'd love to know the technically correct answer to the question.

Clarification!

The majority of the answers seem to think that I want to know whether one can cast a byte to an int and what happens then. Well, that is not the question. I'm asking what the returned type is. In other words, is the author's quoted statement right or wrong? Does the cast to an int happen before or after the returnByte() method actually returns? If this was the real exam and you would have got the question, what would you have answered?

Please see line1 in my code snippet. If what the author say is right, that line would have compiled as the returned value would have been a byte. But it does not compile, the rules of type promotion says that we risk loosing precision if we try to squeeze an int into a byte. For me, that is a proof that the returned value is an integer.

War es hilfreich?

Lösung

Yes, you can do that.

  • The value of the byte expression will be promoted to int before it is returned.

  • The actual return type is as declared in the method signature - int.

IMO, what the author of that book wrote is more or less correct. He just left out explaining the bit about the byte-to-int promotion that happens in the return statement when you "return a byte".

Is the cast happening at the end of our method implementation or is the cast happening back in the main method just before assignment?

The cast (promotion) happens in the returnByte method.

In the real world, this question would not matter as long as one understand the implicit casting and the risk of losing precision.

There is no loss of precision in promoting a byte to an int. If the types were different, there could be loss of precision, but (hypothetically) the loss of precision would be the same wherever the promotion is performed.


The section of the JLS that deals with this is JLS 14.17, which says that the return expression must assignable to the method's declared return type. It doesn't explicitly state that the promotion is done in the method, but it is implied. Furthermore, it is the only practical way to implement this.

If (hypothetically) the conversion was done in the calling method (e.g. main), then:

  • The compiler would need to know what the return statement is doing. This is not possible, given that Java classes can be compiled separately.
  • The compiler would need to know which actual method is going to be called. This is not possible if the method is overridden.
  • If the method contained two (or more) return statements with expressions that have different types, then the compiler needs to know which return will be executed. This is impossible.

If this was the real exam and you would have got the question, what would you have answered?

I would have answered ... "it depends" ... and proceeded to the alternative viewpoints.

Technically speaking the method is returning an int, but the return statement can take any expression whose type can be converted to an int.

But if someone said to me that the method is returning a byte, I would understand what they meant.


Also, as far as i know methods/function use stacks for storage.etc and inside those stacks they store the return addresses not what (type) they are returning to. So, again the ambiguity arises (at least for me). Please correct me if I am wrong.

Yes, technically a method doesn't return a type. (Not even if it returns a Type object. That is an object that denotes a type, not the type itself.) But everyone and his dog would happily say "the returnByte methods returns type int".

So, if you are going to be pedantic, then yes it is ambiguous. But the solution is to not be pedantic.

Andere Tipps

I'm fairly certain it's the same as doing myInt << 24, getting the last eight bits, therefor an imminent loss of precision if the integer is over the value of 255(2^8).

Yes the statement is valid. A byte will always fit into an int comfortably.

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

But if you are doing:

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

Which is what you are doing. Does that help?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top