[Javalist] Segítség! Java7 compiler BUG???
Richard O. Legendi
richard.legendi at gmail.com
2012. Júl. 21., Szo, 19:24:41 CEST
> Csak amíg ott ez érthető és indokoltnak tűnik, addig itt miért így
> kellett?
Azért, mert megtévesztően a trenary operátor valójában egy érték típusú
kifejezés (/conditional expression, /ahogy a neve is mutatja), ezért
ebből a szempontból pontosan ugyanúgy viselkedik, mint egy sima összeadás.
Ricsi
On 2012.07.21. 18:25, Peter Verhas wrote:
> 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 <mailto: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
>
>
>
> _______________________________________________
> 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/ad733999/attachment.html>
További információk a(z) Javalist levelezőlistáról