• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

casting an int to a byte in the return statement

 
Ranch Hand
Posts: 206
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This question is from the self-test exam in K&B SCJP 1.5 Certification text. I have a question about code fragment E. The book says that code fragment E is not a correct answer (I agree with this). I think that there is an additional reason why code fragment E is not a valid answer. byte m2(short s) { return 42; } returns an int instead of a byte. Don't you have to cast the integer in the return statement to a byte, e.g. return (byte)42; ? Will there be a compiler error because of this oversight? Thanks.

1. Given the following,

interface Base {
boolean m1 ();
byte m2(short s);
}
Which code fragments will compile? (Choose all that apply.)
A. interface Base2 implements Base { }
B. abstract class Class2 extends Base {
public boolean m1() { return true; } }
C. abstract class Class2 implements Base { }
D. abstract class Class2 implements Base {
public boolean m1() { return (true); } }
E. class Class2 implements Base {
boolean m1() { return false; }
byte m2(short s) { return 42; } }

Answer:
C and D are correct. C is correct because an abstract class doesn't have to implement any
or all of its interface's methods. D is correct because the method is correctly implemented.
A is incorrect because interfaces don't implement anything. B is incorrect because classes
don't extend interfaces. E is incorrect because interface methods are implicitly public, so
the methods being implemented must be public. (Objective 1.1)
 
Sheriff
Posts: 3063
12
Mac IntelliJ IDE Python VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Henry!

Do you not have access to a Java compiler? It seems like it would be easy just type this code into a Java file and see if it compiles.

I believe the rule is you can assign a numeric literal (i.e., a number, not a variable) to a byte as long as it is between -128 and 127. If the literal is outside that range, you need a cast and you will be lopping off significant bits when you do it.
 
Harry Henriques
Ranch Hand
Posts: 206
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Greg,

I didn't think to try-out my Java compiler. You are correct about the compiler accepting a number in the range of -128 to 127 for a byte. I got another interesting error when I tried to compile the code below. Clearly, 16 is within the range of a short, but the compiler will not implicitly downcast an int literal to a short in the argument list. See the error below. But, casting an int literal to a short, i.e. (short)16, works fine.

Thanks,
Harry

public class ByteTest{

public static void main(String [] args){
ByteTest b = new ByteTest();
System.out.println( b.m2( 16 ) );
}

byte m2(short s){ return 42; }

}

C:\TEMP>javac ByteTest.java
ByteTest.java:5: m2(short) in ByteTest cannot be applied to (int)
System.out.println( b.m2( 16 ) );
^
1 error
 
Greg Charles
Sheriff
Posts: 3063
12
Mac IntelliJ IDE Python VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oh, definitely you should be playing with a compiler when you go through these lessons. Go beyond the lessons if you can. Play "what if" games, like what if I put in a negative number? What if I use a static final? That's part of getting a real understanding for how things work.

As for your new question, yeah, that's a bit strange. I'm sure the reasoning is buried in the Java language specification somewhere. I imagine it goes something like this: when we're returning a literal value or assigning it to a variable, we can tell at compile time if it will fit in the slot, so we let it compile. Finding the correct method, however, is done at run-time. Remember you could have several m2() methods taking different parameters, one a byte, one a short, one a long, etc. At run-time, 16 is a long, so the run-time system is going to search for an m2(long) method to run. You haven't defined one, so the run-time will blow up ... or it would, but the compiler is smart enough to catch it for you first.
 
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Greg Charles wrote:Finding the correct method, however, is done at run-time.


Actually, not in this case. Overridden methods are found at runtime, but overloaded methods are found at compile time.

The thing is, any whole number is an int unless you add an L, F or D for long, float or double respectively. So "16" is an int, never a short. The compiler is therefore looking for a method "m2" that takes one single int as parameter.

When assigning the compiler is smart enough to see that it fits in the range of short, but only when assigning. Never on method calls.
 
Greg Charles
Sheriff
Posts: 3063
12
Mac IntelliJ IDE Python VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Oh, shoot. Rob is right, both about the method-binding and that 16 will default to an int, not a long. The first thing is very important. The run-time type of an object will be examined to determine which implementation of an overridden method to use . This is also called late-binding and is necessary for polymorphism to work. The same thing is not true for overloaded methods, which are bound at compile time. I guess I keep forgetting that because it doesn't seem logical. Many people advise avoiding overloading altogether for that reason, though I think that may be overkill. Exercise some caution though.

The int/long thing was just a brain-f... um, a lapse of concentration. Obviously 16 is an int literal (4 byte integer), while 16L is a long (8 byte integer).

Sorry about that Henry!
 
Rob Spoor
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Greg Charles wrote:The int/long thing was just a brain-f... um, a lapse of concentration. Obviously 16 is an int literal (4 byte integer), while 16L is a long (8 byte integer).


Fortunately, int to long widening is allowed, so a method m2 that takes a long would accept 16. It's byte, short and char parameters that don't work.

Sorry about that Henry!


Don't you mean Harry?
 
Greg Charles
Sheriff
Posts: 3063
12
Mac IntelliJ IDE Python VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Excuse me, I'm having a conversation with my imaginary friend Henry and it's private!

Don't pay attention to the mean man Henry!

 
reply
    Bookmark Topic Watch Topic
  • New Topic