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

Peter Verhas peter at verhas.com
2012. Júl. 21., Szo, 18:25:39 CEST


Valóban azt írja a szabvány, hogy típuskonverziót fog végezni, és az eredmény pontosan ugyanúgy Double lesz, mint ahogy egy Long és egy Double összeadása során is Double-t kapunk. Csak amíg ott ez érthető és indokoltnak tűnik, addig itt miért így kellett? Nah, de mindegy. Lényeg, hogy ez nem bug, hanem feature.

--
Verhás Péter
peter at verhas.com
+36(30)9306805
skype: verhas




On 2012.07.21., at 18:19, Böszörményi Péter wrote:

> 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
> _______________________________________________
> Javalist mailing list
> Javalist at lists.javaforum.hu
> http://lists.javaforum.hu/mailman/listinfo/javalist

--------- következő rész ---------
Egy csatolt HTML állomány át lett konvertálva...
URL: <http://lists.javaforum.hu/pipermail/javalist/attachments/20120721/1ca25937/attachment.html>


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