[Javalist] Segítség! Java7 compiler BUG???

Böszörményi Péter zmblevlist at gmail.com
2012. Júl. 21., Szo, 18:19:49 CEST


Szerintem ez nem bug. Magyarazatom nincs, de talan ezek adnak otletet:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.25:
The type of a conditional expression is determined as follows:
[...]
* Otherwise, binary numeric promotion (§5.6.2) is applied to the operand  
types, and the type of the conditional expression is the promoted type of  
the second and third operands.

http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2:
When an operator applies binary numeric promotion to a pair of operands,  
each of which must denote a value that is convertible to a numeric type,  
the following rules apply, in order:
[...]
* If either operand is of type double, the other is converted to double.


On Sat, 21 Jul 2012 17:56:41 +0200, Peter Verhas <peter at verhas.com> wrote:

> A következő osztályt alkottam:
>
> public class Bug{
>     public static Number q(Number in) {
>         return in instanceof Long ? 1L : 1.0;
>     }
> }
>
> Ebből a következős sikerült a Java-nak fordítania:
> verhasp:test verhasp$ javac Bug.java
> verhasp:test verhasp$ javap -v Bug.class
> Classfile /Users/verhasp/projects/test/Bug.class
>   Last modified 2012.07.21.; size 392 bytes
>   MD5 checksum 7a7a2b3ddba08525477330df16f4ca78
>   Compiled from "Bug.java"
> public class Bug
>   SourceFile: "Bug.java"
>   minor version: 0
>   major version: 51
>   flags: ACC_PUBLIC, ACC_SUPER
> Constant pool:
>    #1 = Methodref          #5.#15         //   
> java/lang/Object."<init>":()V
>    #2 = Class              #16            //  java/lang/Long
>    #3 = Methodref          #17.#18        //   
> java/lang/Double.valueOf:(D)Ljava/lang/Double;
>    #4 = Class              #19            //  Bug
>    #5 = Class              #20            //  java/lang/Object
>    #6 = Utf8               <init>
>    #7 = Utf8               ()V
>    #8 = Utf8               Code
>    #9 = Utf8               LineNumberTable
>   #10 = Utf8               q
>   #11 = Utf8               (Ljava/lang/Number;)Ljava/lang/Number;
>   #12 = Utf8               StackMapTable
>   #13 = Utf8               SourceFile
>   #14 = Utf8               Bug.java
>   #15 = NameAndType        #6:#7          //  "<init>":()V
>   #16 = Utf8               java/lang/Long
>   #17 = Class              #21            //  java/lang/Double
>   #18 = NameAndType        #22:#23        //   
> valueOf:(D)Ljava/lang/Double;
>   #19 = Utf8               Bug
>   #20 = Utf8               java/lang/Object
>   #21 = Utf8               java/lang/Double
>   #22 = Utf8               valueOf
>   #23 = Utf8               (D)Ljava/lang/Double;
> {
>   public Bug();
>     flags: ACC_PUBLIC
>     Code:
>       stack=1, locals=1, args_size=1
>          0: aload_0
>          1: invokespecial #1                  // Method  
> java/lang/Object."<init>":()V
>          4: return
>       LineNumberTable:
>         line 1: 0
>
>   public static java.lang.Number q(java.lang.Number);
>     flags: ACC_PUBLIC, ACC_STATIC
>     Code:
>       stack=2, locals=1, args_size=1
>          0: aload_0
>          1: instanceof    #2                  // class java/lang/Long
>          4: ifeq          11
>          7: dconst_1
>          8: goto          12
>         11: dconst_1
>         12: invokestatic  #3                  // Method  
> java/lang/Double.valueOf:(D)Ljava/lang/Double;
>         15: areturn
>       LineNumberTable:
>         line 3: 0
>       StackMapTable: number_of_entries = 2
>            frame_type = 11 /* same */
>            frame_type = 64 /* same_locals_1_stack_item */
>           stack = [ double ]
>
> }
>
>
> A biztonság kedvéért command line-ból fordítottam ezzel:
>
> verhasp:test verhasp$ java -version
> java version "1.7.0_04"
> Java(TM) SE Runtime Environment (build 1.7.0_04-b21)
> Java HotSpot(TM) 64-Bit Server VM (build 23.0-b21, mixed mode)
>
> Ha értő szem megnézi a kódot, akkor láthatja (no meg tapasztalhatja is  
> futtatás közben), hogy ez bizony mindig Double értéket fog visszaadni,  
> akkor is, ha paraméter 'in' Long. Ha megfordítom a feltételt, és persze  
> a feltételes kifejezés két felét is ezzel, illetve ha nem azt vizsgálom,  
> hogy Long-e, hanem azt, hogy Double, akkor is mindig Double értéket akar  
> visszaadni a javap disassembly alapján. Megpróbáltam 1.6.0_33 verziójú  
> Java-val is (nem az összes verziót, annyi türelmem nincs), ott is  
> ugyanaz az eredmény.
>
> Azért mielőtt bugreportot küldenék az ORACLE-nak, megkérdezném a  
> tisztelt társaságot, hogy mit nézek itt nagyon be?
>
> A workaround megvan, mert a
>
> public class Bug{
>     public static Number q(Number in) {
>         if( in instanceof Long )
>         return 1L; else return 1.0;
>     }
> }
>
> működik rendesen.
>
> --
> Verhás Péter
> peter at verhas.com
> +36(30)9306805
> skype: verhas
>
>
>
>


-- 
Üdvözlettel,
Böszörményi Péter


További információk a(z) Javalist levelezőlistáról