• 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
  • Devaka Cooray
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Jeanne Boyarsky
  • Tim Cooke
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Tim Moores
  • Mikalai Zaikin
  • Carey Brown
Bartenders:

narrowing conversions

 
Ranch Hand
Posts: 148
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
author
Posts: 14112
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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).

 
Ranch Hand
Posts: 85
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.

 
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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?
 
Ranch Hand
Posts: 37
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
 
Let nothing stop you! Not even this tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic