Why Short.valueOf (n) requires listing

As per this answer, int constant is implicitly convertible to short type.

But in my unit test, I want to test the getValue () function that returns a Short .

assertEquals(obj.getValue(), 42); 

      

Obviously this doesn't work, so I am trying to use Short.valueOf

assertEquals(obj.getValue(), Short.valueOf(42)); 

      

However, this still complains - despite the above implicit conversion - so I have to use a literal.

assertEquals(obj.getValue(), Short.valueOf((short)42)); 

      

Short.valueOf ((short) 5) seems a little messy! Is there a cleaner way? (the new short ("42") is equally awful!)

+3


source to share


4 answers


This is because converting a number from int

to short

may fail (overflow) as it is a narrowing of the primitive conversion . In theory, the compiler could recognize that the argument is a constant expression, and it can determine if the conversion is valid at compile time. But this is not the case.

A cleaner way:

Short s = 42; //autoboxing is done here
assertEquals(obj.getValue(), s );

      



The reason for the above is that the rules for assigning variables are different. This is where the compiler actually checks if the constant expression can be converted to short

without overflow.

Additionally, if the expression is a constant expression (Β§ 15.28) of type byte, short, char, or int:

A narrowing primitive conversion can be used if the type of the variable is byte, short, or char, and the value of the constant expression is represented in the type of the variable.

A narrowing of the primitive conversion followed by the boxing conversion can be used if the type of the variable is:

Byte and constant expression value can be represented in byte type.

In short, the value of the constant expression is represented in type short.

The sign and value of a constant expression can be represented as char.

This is in bold.

+8


source


The other answers explain why you have this problem. A cleaner option for your code might be:

assertEquals(obj.getValue().intValue(), 42); 

      

Although biziclop indicates , this will throw a NullPointerException if it getValue()

returns null. While this will still fail your test, it won't be so obvious what went wrong.



Of course, if null values ​​are not valid, you should short

not return a short

. In this case, you don't need any casts:

assertEquals(obj.getValue(), 42); // fine, if getValue() returns a short

      

+1


source


The Short class does not have a method that takes int

as a parameter, so

Short.valueOf(1); // compilation error

      

but casting to (short) 1

Short.valueOf((short) 1);

      

works because a short method is used as a parameter. Why can't this compiler do the casting automatically because

Narrowing primitive conversions can lose information about the total value of a numeric value, and can also lose precision and range.

+1


source


JLS states

An Integer literal is long if it is suffixed with an ASCII letter L or l (ell); otherwise, it is of type int (Section 4.2.1).

Therefore, you need to give it to short

.

You might also be interested in Why are there no bytes or short literals in Java?

0


source







All Articles