File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes narrowing conversions Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "narrowing conversions" Watch "narrowing conversions" New topic
Author

narrowing conversions

James Clarke
Ranch Hand

Joined: Oct 04, 2004
Posts: 148
class Class2{

static byte m2(short s) {return 42;}//line 3

public static void main(String [] args){
System.out.println(m2((short)1)); // line 6
}
}

The above code compiles and runs fine, but if I remove the explicit conversion at line 6 I get the following compilation error:

Class2.java [6:1] m2(short) in Class2 cannot be applied to (int)
System.out.println(m2(1));
^
I expected to get the same error on line 3. Are implicit narrowing conversions permitted for return values ie. int value returned by method that declares a byte return type ? This example suggests that to be the case.

Thanks
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
From http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#12687


Method invocation conversions specifically do not include the implicit narrowing of integer constants which is part of assignment conversion (�5.2). The designers of the Java programming language felt that including these implicit narrowing conversions would add additional complexity to the overloaded method matching resolution process (�15.12.2).


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Nina Binde
Ranch Hand

Joined: Sep 24, 2004
Posts: 85
I was digging thru the previous questions and I failed to understand this one question even after going thru the link which Ilja suggested.

Could anyone throw more light into this as to why the return value does not throw any compilation error even though we dont use explicit casting when narrowing the primitive from int to byte whereas when we remove the cast in the call to the method m2(1), it throws a compilation error.

Thanks for the answers.
Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271
From the JLS §5.2 Assignment Conversion:


Assignment conversion occurs when the value of an expression is assigned (�15.26) to a variable: the type of the expression must be converted to the type of the variable. Assignment contexts allow the use of an identity conversion (�5.1.1), a widening primitive conversion (�5.1.2), or a widening reference conversion (�5.1.4). In addition, a narrowing primitive conversion may be used if all of the following conditions are satisfied:

- The expression is a constant expression of type byte, short, char or int.
- The type of the variable is byte, short, or char.
- The value of the expression (which is known at compile time, because it is a constant expression) is representable in the type of the variable.

If the type of the expression cannot be converted to the type of the variable by a conversion permitted in an assignment context, then a compile-time error occurs.


SCJP Tipline, etc.
rimzim sinha
Greenhorn

Joined: Oct 26, 2004
Posts: 17
Even if i assign is to a variable as given belowe ,we dont get an error;
Can some one please explain a little more?

class test{

static byte m2(short s) {return 42;}//line 3

public static void main(String [] args){
byte x = m2((short)1);
System.out.println(m2((short)1)); // line 6
}
}
Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271
Why would you get an error from that code snippet? The method m2 returns a byte which you are assigning to a byte. What's wrong with that?
rengarajan vaikuntam
Ranch Hand

Joined: Oct 04, 2004
Posts: 37
Let me try to xplain. Im also new if iam wrong let someone else correct me.

First let us see the method
static byte m2(short s)
The method declares very clearly that it is going to take a short as argument.It has got a memory capacity of only 16 bits.so if u call the method
m2(1);
here 1 is an integer even though this is well within the range of a short this is with 32 bits so the compiler complains that it cannot hold an integer in the place of short its a narrowing conversion so a explicit cast is needed.Now if you say

short a = 1;
then call the method
m2(a);
now the value 1 stored in the var a is a short so this also compiles without any problem.

Now the return statement.The method declares
return 42;
Here 42 is a compile time constant and it is well within the range of byte so this is fine.Whatever value you are going to pass in to this method and whatever operations are performed in the method it is going to return only 42.So there is no need of any casting here.
But if you say
return s+1;
here it will not compile and here you will need a explicit cast even though if it is going to be in the range of byte, but you dont know s is a variable the value of s might change during another call so here it needs a cast
return(byte)(s+1);
Hope this clears.
Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271
Originally posted by rengarajan vaikuntam:
Hope this clears.


It seems to me that you understand this all very well - I don't understand what you're confused about. The thing to remember is that different conversions can have different rules. Specifically, assignment conversion is different from method invocation conversion.

When you're doing an assignment, if you're assigning a constant value to a variable, the compiler can look at that and see if it is within the range of the target variable. If it is, the compiler will add an implicit cast. If it's not (or the value you're assigning is not constant), you'll get a compiler error without an explicit cast. Return types follow this rule, as well so returning 15 from a method that returns a byte is fine.

When you're invoking a method, you get no such benefit from the compiler. It takes things at face value in such a case. If you try to pass 32 to a method, you're passing an int, regardless of what types 32 might fit into. You're passing an int.

I hope that helps,
Corey
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: narrowing conversions
 
Similar Threads
casting error #2
return type
Doubt on implicit casting
Implicit casting with primitives/wrapper classes
Compile time constant