3

I have decompiled a Java class which contain this line :

DatabaseError.throwSqlException((int)23);

Until now i believe that Java consider that literal numeric value is int, So why they cast 23 ? And in general how Java deal with hard coded numeric values ?

Edit: Im not interested in this specific case, but interested to go deeper with Java in general.

54l3d
  • 3,913
  • 4
  • 32
  • 58
  • Is this specifc line the result of the decompilation process or is this what source file contains? – Tunaki Nov 18 '15 at 14:13
  • 1
    a hardcoeded number either represents an `int` or a `double` if it is written as `.0` or `0.0`. – SomeJavaGuy Nov 18 '15 at 14:14
  • @Tunaki Godd question, this is a result of decompiled class, do you think that decompiler may give something different than source code ? – 54l3d Nov 18 '15 at 14:18
  • 2
    You could be fooled by the decompiler but anyway, the int cast in unnecessary – Tunaki Nov 18 '15 at 14:19
  • 1
    How is this a duplicate? OP is asking why a decompiler is emitting a cast; dupe is asking why a too-large integer causes a compiler error. – Colonel Thirty Two Nov 18 '15 at 14:24
  • 2
    @ColonelThirtyTwo No, OP is asking "And in general how Java deal with hard coded numeric values ?" which is answered over there but also in others posts. An integer literal is an `int`, that's all there is to it. – Tunaki Nov 18 '15 at 14:44

2 Answers2

2

I still believe it is related to the used decompiler.

It can be assumed that the signature of the method is DatabaseError.throwSqlException(int i).

The statement DatabaseError.throwSqlException((int)23) would be compiled as DatabaseError.throwSqlException(23) - the literal is of type int and the method parameter type is of type int

the DatabaseError.throwSqlException((int)23L) would be compiled as DatabaseError.throwSqlException(23) - the value can be stored without precision lose in an int and the method parameter type is of type int

The byte code is in both cases

bipush 23    // push the value on the operand stack
invokestatic // DatabaseError.throwSqlException:(I)V

Decompiled it would be DatabaseError.throwSqlException(23). Because in case it was 23L in the source code, this information isn't in the bytecode.

A bytecode similar to DatabaseError.throwSqlException((int)23) could be

ldc2_w       // push a long from constant pool on the operand stack
l2i          // convert top value on the operand stack from long to int 
invokestatic // DatabaseError.throwSqlException:(I)V

But this is decompiled by jad and jd-gui to DatabaseError.throwSqlException((int)23L) (notice the L after the value).

edit The above bytecode is decompiled by CFR as DatabaseError.throwSqlException((int)23). So it really depend on the used decompiler.

SubOptimal
  • 22,518
  • 3
  • 53
  • 69
0

According to the Oracle Java Tutorials Primitive Data Types:

An integer literal is of type long if it ends with the letter L or l; otherwise it is of type int.

As for the particular decompiled statement:

DatabaseError.throwSqlException((int)23);

Only the person that coded the statement could answer for sure. Perhaps he wasn't sure if the 23 was a byte or an int.

Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111