When I am writing this code I am getting error
public class MethodOverloading
{
void m(short i)
{
System.out.println("SHort");
}
public static void main(String[] args)
{
MethodOverloading ml=new MethodOverloading();
ml.m(10);
}
}
I am getting error that m(short) is not applicable for m(int) but when I am
assigning int value to short then no error then if am not able to pass int
value as an argument to method that accepts short then how short variable is accepting int value as below?
short d=10;
System.out.println(d);
Narrowing conversion can occur in an assignment unlike literals being passed to a method. From the JLS
A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.
You have to cast the int to short, because 10 is considered like an int not a short :
ml.m((short)10);
m1.m((short) 10);
Cast the 10 (since there's no type associated with it Java assumes it's a 32-bit int instead of a 16-bit short) to a short.
This is static binding, and the assignment operator '=' is not strict on down casting.But method binder is strict on type. Just imagine you have one more method void m(int i) along with void m(int i) the method binder must bind the call to the right method. So it must be strict.
In short s = 10 case, jdk will downcast the value on compilation, so the value will be assigned to s will be down caste of short 10, also if you try to assign a real int range value say 99999999 it will not compile.
Finally static method binding is strict on type.
Related
I have the following code in Java :
class Boxing
{
public static void main(String args[])
{
short s = 10;
Integer iRef = s;
}
}
Why does it produce an error in compilation? If I explicitly typecast the short to an integer in the expression, it compiles successfully. Since I'm using a short in an expression isn't the type of that supposed to be an integer by default without requiring the explicit case?
You want to have two things happening here: widening and auto-boxing.
Unfortunately, Java does only one of the two automatically. The reason for that is most likely that autoboxing was introduced fairly late (in Java5), and they had to be careful to not break existing code.
You can do
int is = s; // widening
Short sRef = s; // autoboxing
Integer iRef = (int) s; // explicit widening, then autoboxing
Here´s the documentation from JLS 5.1.7
Boxing conversion converts expressions of primitive type to corresponding expressions of reference type. Specifically, the following nine conversions are called the boxing conversions:
From type boolean to type Boolean
From type byte to type Byte
From type short to type Short
From type char to type Character
From type int to type Integer
From type long to type Long
From type float to type Float
From type double to type Double
From the null type to the null type
Basicly the direct conversion from short to Integer is not part of the autoboxing process of Java.
The autoboxing, as provided above, is only able to implicity cast the representing primitive type to it´s representing Wrapper class. Since this is not the case it will cause a compile time error.
Boxing conversion converts expressions of primitive type to corresponding expressions of reference type. Specifically, the following nine conversions are called the boxing conversions:
From type boolean to type Boolean
From type byte to type Byte
From type short to type Short
From type char to type Character
From type int to type Integer
From type long to type Long
From type float to type Float
From type double to type Double
From the null type to the null type
Reference: Conversions and Promotions Reference
In the code considered.
class Boxing
{
public static void main(String args[])
{
short s = 10;
Integer iRef = s;
}
}
Integer extends java.lang.Number. And java.lang.Short also extends java.lang.Number. But Short and Integer are not directly related if you wanted you can run the following program.
class Boxing
{
public static void main(String args[])
{
short s = 10;
Number iRef = s;
}
}
It will run without producing any error.
Java attempts to perform auto-widening, then auto-boxing, then auto-upcasting, but will not perform two of these for the same assignment. This is explained and diagrammed here, for the related case of method parameter assignment.
I have a method that accept one parameter of type short.
public void doSomething(short value) {
//DO STUFF
}
And I can call it this way:
short value = 3;
doSomething(value);
But not this another one:
doSomething(3);
Why? Is there a way to denote that this parameter is a short and not an int?
You can call it this way :
doSomething((short)3);
Without casting, 3 will always be an int literal.
The reason
public void doSomething(short value) {
//DO STUFF
}
can be called as
short value = 3;
doSomething(value);
cause value is already short
When you call it like doSomething(3); 3 is considered as integer and cannot be casted to short implicitly.
Basically doSomething(3); would require a
public void doSomething(int value) {
//DO STUFF
}
method to go with.
However you can cast 3 to short and can call the method as:
doSomething((short)3);
In Java, arithmetic expressions on the right hand side of the assignment evaluates to int by default. Look at this surprising example:
short a = 1;
short b = 2;
short c = a + b; // Error!
You need to explicitly cast to short as already mentioned in other answers, or change the method's signature to accept int instead.
It's worth mentioning that in terms of space short takes the same space as int if they are local variables, class variables or even instance variables since in most systems, variables addresses are aligned, I would simply change the signature of the method to accept an int instead and wouldn't complicate things.
java is not able to call any overload method as shown below :-
class LspTest{
public void add(int a, float b){
System.out.println("First add");
}
public void add(float a, int b){
System.out.println("second add");
}
public static void main(String [] a){
LspTest test = new LspTest();
test.add(1,1);
}
}
Please explain i am confused in this.
In your methods you are having parameters (int, float) and (float, int) but when calling the method you are passing both the int (1,1) values. The Java complier can auto type cast float to int whenever needed. But in this case compiler cannot decide auto type cast which int to float. Therefore it shows ambiguity.
You need to call it test.add(1f, 1); or test.add(1,1f); i.e. specify which value is int and which value is float.
P.S. To specify a value to be float you can write f with it.
When you initialise with literal values, in this case, compiler won't be able to infer the exact type. Therefore, it does not know which overload to call and returns the error that the reference to add is ambiguous. You can fix this by casting the arguments to the appropriate type, or even better, creating typed local variables initialised with 1 and passing the variables as parameters, like so:
int a = 1;
float b = 1;
LspTest test = new LspTest();
test.add(a,b);
There is an ambiguity here, and the Java compiler cannot figure out which method to call. Use test.add((float) 1, 1) or test.add(1, (float) 1) to explicitly tell which method you want.
This is the clear case of ambiguity which leads to a Compile Error.
Java compiler supports the type promotion. First of all, it'll checks for more specific data type if not match then it'll promote to next data type.
Java compiler will supports the type promotion in following order.
byte --> short --> int --> long --> float --> double
As your parameters (int,int) can be auto-promoted to float, java compiler can't decide in which one to invoke as both of your methods accepts the (1,1)
I saw below question posted on this site.
"What happens when we pass int arguments to the overloading method having float as a parameter for one method and another having double param".
I thought I understood the concept and wrote this code:
public class TestClass {
public static void main(String args[])
{
TestClass t=new TestClass();
t.sum(1/4);
}
void sum(double d)
{
System.out.println("Double==="+d);
}
void sum(int i)
{
System.out.println("Integer==="+i);
}
void sum(short s)
{
System.out.println("Short==="+d);
}
}
According to my understanding explained on this site (as mentioned above), I thought it will print Short===0, but to my surprise it prints Integer===0. Can any one explain this to me?
First of all, these are overloaded methods, not overridden methods.
1 and 4 are integers. Therefore 1/4 is an integer division, returning 0.
Therefore, the method being called is sum(int i).
sum(short s) would never be called for an int parameter, since that would require a narrowing primitive conversion (JLS 5.1.3), that may cause data loss, and is not allowed in method invocation conversion (JLS 5.3). Such a conversion can be done with an explicit cast.
If you remove the int version, sum(double d) would be called, and if you remove the double version, the code won't compile.
In order to call the short version, you must cast the parameter to short :
t.sum ((short)(1/4));
If you don't explicitly tell the compiler what are the types of 1 and 4, it assumes they are of type int. Then, / operator will apply integer division and will produce another int (which will be 0.)
After that, the method with the most specific to integer parameter type will be invoked. In your case, this will be sum(int i).
If you want to invoke some of the other overloaded methods, you will have to explicitly:
do a cast. For example, sum((short) (1/4)); will invoke sum(short s) due to the cast.
point the type of the operands. For example, sum(1d/4) will invoke sum(double d), since 1d/4 will result to double
For integer number, the type int is a default choice. So, although 1 and 4 can be defined as both int or short, since you did not defined anything, the compiler identified 1 and 4 as int and therefore it entered into the function for 1/4 division (0), which took the parameter int.
Can someone please explain how/why is this allowed in Java?
public class Test {
private int text;
public Integer getText() {
return text;
}
I am basically having the wrapper class as the return type, while I am infact returning a primitive.
Because Java supports Autoboxing and Unboxing in versions 5 and up. That is an example of the former, but the later is equally important (and the reverse conversion). Per the link,
Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes.
Consider the following code: (From: http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html)
List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
li.add(i);
Although you add the int values as primitive types, rather than Integer objects, to li, the code compiles. Because li is a list of Integer objects, not a list of int values, you may wonder why the Java compiler does not issue a compile-time error. The compiler does not generate an error because it creates an Integer object from i and adds the object to li. Thus, the compiler converts the previous code to the following at runtime:
List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
li.add(Integer.valueOf(i));
Converting a primitive value (an int, for example) into an object of the corresponding wrapper class (Integer) is called autoboxing. The Java compiler applies autoboxing when a primitive value is:
Passed as a parameter to a method that expects an object of the corresponding wrapper class.
Assigned to a variable of the corresponding wrapper class.
From javadocs : Since java 5 Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes. For example, converting an int to an Integer, a double to a Double, and so on.
The java compiler applies autoboxing usually when -
Passed as a parameter to a method that expects an object of the
corresponding wrapper class.
Assigned to a variable of the corresponding wrapper class.
For the sake of performance, not everything in Java is an object. There are also primitives, such as int, long, float, double, etc.
For example java.lang.Integer class :-
It wraps an int.
Has two static final fields of type int: MIN_VALUE and MAX_VALUE.
MIN_VALUE contains the minimum possible value for an int (-2^31) and MAX_VALUE the maximum possible value for an int (2^31 - 1).
It also has two constructors - public Integer (int value) & public Integer (String value).
Integer has the no-arg byteValue, doubleValue, floatValue, intValue, longValue, and shortValue methods that convert the wrapped value to a byte, double, float, int, long, and short, respectively.
In addition, the toString method converts the value to a String.
Static methods parse a String to an int (parseInt) and convert an int to a String (toString).
class AutoBox {
public static void main(String args[]) {
// autobox an int
Integer a = 100;
// auto-unbox
int b = a;
System.out.println(b + " " + a); // displays 100 100
}
}
This feature has been added in Java 5.
text gets converted automatically into Integer by compiler. So basically its a syntactic sugar that can shorten your code (otherwise you would do conversions back and forth by yourself). Of course it has its price and if this happens a lot (I mean really a lot, big loops, frequent invocations and so forth), it can become a performance issue, so when using it, just remember the it happens under the hood and you'll be fine.
Integer.valueOf(text)
is called under the hood
The feature is called autoboxing btw
Hope this helps