Hlavní navigace

Pohled pod kapotu JVM (3.část - pokračování popisu struktury souborů .class)

Pavel Tišnovský

Dnes se společně již potřetí vrátíme ke struktuře bajtkódu, tj. k souborům s koncovkou .class. Řekneme si, jakým způsobem jsou v bajtkódu uloženy další důležité informace: příznaky třídy či rozhraní, jméno implementované třídy, jméno nadtřídy a konečně i seznam všech implementovaných rozhraní.

Obsah

1. Pohled pod kapotu JVM (3.část – pokračování popisu struktury souborů .class)

2. Definice příznaků třídy či rozhraní

3. Úprava demonstračního dekompileru a příznaky nastavené u vybraných souborů .class pocházejících z balíčku java.lang

4. Jméno třídy/rozhraní/výč­tu/anotace a jméno nadřazené třídy

5. Jména tříd a nadřazených tříd u vybraných souborů .class pocházejících z balíčku java.lang

6. Seznam implementovaných rozhraní

7. (Prozatím) finální verze dekompileru souborů .class – doplnění o výpis všech implementovaných rozhraní

8. Výpis všech implementovaných rozhraní u vybraných souborů .class pocházejících z balíčku java.lang

9. Odkazy na Internetu

1. Pohled pod kapotu JVM (3.část – pokračování popisu struktury souborů .class)

V předchozích dvou částech seriálu o programovacím jazyce Java i o vlastnostech virtuálního stroje tohoto jazyka jsme si podrobně popsali strukturu constant poolu, jenž tvoří nedílnou součást každého bajtkódu, tj. každého souboru s koncovkou .class generovaného překladačem Javy (většinou programem javac). Pro výpis obsahu constant poolu byl použit relativně jednoduchý nástroj naprogramovaný v céčku, který budeme v dnešním článku postupně rozšiřovat. Připomeňme si, že v constant poolu jsou umístěny všechny řetězcové konstanty (literály), celočíselné i reálné konstanty, jména tříd, signatury metod a konečně i signatury atributů. Signatura metody se skládá z jejího jména, zakódovaného návratového typu i zakódovaných typů všech argumentů metody. U signatury atributu je vedle jeho jména uložen (opět v zakódované podobě) i jeho datový typ. V dnešním článku si alespoň zhruba popíšeme další údaje, které je možné v souborech .class nalézt.

Celkovou strukturu bajtkódu jsme si již popsali. Z minula již víme, co obsahuje hlavička souborů .class a známe i způsob uložení informací v constant poolu. Další údaje v bajtkódu jsou však neméně důležité. Jedná se především o příznaky třídy či rozhraní, informace o jméně třídy i nadtřídy, seznam implementovaných rozhraní, atributy třídy a konečně i o nejdůležitější typ údajů – instrukce tvořící těla jednotlivých metod:

+-----------------------------------+
|  Hlavička                         |
+-----------------------------------+
|  Constant pool                    |
|  .....                            |
|  .....                            |
|  .....                            |
+-----------------------------------+
|  Definice příznaků třídy/rozhraní |
+-----------------------------------+
|  Jméno třídy a nadtřídy           |
+-----------------------------------+
|  Implementovaná rozhraní          |
|  .....                            |
+-----------------------------------+
|  Atributy třídy                   |
|  .....                            |
+-----------------------------------+
|  Kódy jednotlivých metod          |
|  .....                            |
|  .....                            |
|  .....                            |
+-----------------------------------+
|  Další metadata třídy             |
+-----------------------------------+

2. Definice příznaků třídy či rozhraní

Pojďme si tedy podrobněji popsat další údaje, z nichž je sestaven každý javovský bajtkód. Ihned za posledním záznamem uloženým v constant poolu se nachází další důležitá informace. Jedná se o příznaky přiřazené ke třídě, k výčtovému typu, k rozhraní či k anotaci, z níž soubor .class vznikl. Všechny tyto příznaky jsou společně zakódované ve dvojici bajtů, jejichž pořadí opět (stejně jako u jiných typů záznamů v bajtkódu) odpovídá pořadí big endian. V následující tabulce jsou vypsány všechny příznaky, s nimiž se můžeme setkat v různých verzích bajtkódu. Prvních pět příznaků se používá již od prvních verzí JVM, další příznaky byly postupně přidávány s tím, jak se rozšiřovala syntaxe a samozřejmě i sémantika programovacího jazyka Java. Jedná se především o příznak ACC_ANNOTATION, který se objevil společně s anotacemi (Java 5) a taktéž o příznak ACC_ENUM označující výčtový typ (enumeration):

# Jméno příznaku Bitová maska Význam příznaku
1 ACC_PUBLIC 0×0001 veřejná třída či rozhraní
2 ACC_FINAL 0×0010 finální třída (nelze z ní vytvářet další odvozené třídy)
3 ACC_SUPER 0×0020 mění význam volání metod nadtřídy pomocí instrukce invokespecial
4 ACC_INTERFACE 0×0200 příznak označující, že se jedná o rozhraní
5 ACC_ABSTRACT 0×0400 abstraktní třída (nelze vytvořit její přímou instanci)
6 ACC_SYNTHETIC 0×1000 obvykle se jedná o třídu generovanou přímo překladačem (neexistuje k ní zdrojový kód)
7 ACC_ANNOTATION 0×2000 jedná se o anotaci
8 ACC_ENUM 0×4000 jedná se o výčet

Vzhledem ke vztahu mezi výše popsanými příznaky a sémantikou programovacího jazyka Java je zřejmé, že zdaleka ne všechny kombinace příznaků jsou korektní. Například platí, že příznak ACC_INTERFACE by měl být použit společně s příznakem ACC_ABSTRACT. Podobně platí, že pokud se jedná o anotaci, tj. je nastaven příznak ACC_ANNOTATION, měl by být společně nastaven příznak ACC_INTERFACE. Taktéž je pochopitelné, že příznaky ACC_FINAL a ACC_ABSTRACT nesmí být nastaveny společně – nelze totiž vytvořit finální a současně i abstraktní třídu. Speciální význam má příznak ACC_SUPER, který mění význam instrukce invokespecial. O významu této instrukce se zmíníme v následující části tohoto seriálu.

3. Úprava demonstračního dekompileru a příznaky nastavené u vybraných souborů .class pocházejících z balíčku java.lang

Přidání výpisu příznaků třídy, rozhraní, anotace či výčtu do pomocného nástroje popsaného v předchozí části tohoto seriálu je velmi snadné, protože postačuje ihned po zpracování constant poolu přečíst z bajtkódu dvojici bajtů nacházejících se za posledním záznamem uloženým v constant poolu a následně správně interpretovat jednotlivé bity uložené v této dvojici bajtů. Do programu tedy stačí doplnit jeden výčet (skupinu celočíselných konstant) a jednu novou funkci:

/*
 * Priznaky tridy ci rozhrani.
 */
enum
{
    ACC_PUBLIC     = 0x0001,     /* verejna trida/rozhrani */
    ACC_FINAL      = 0x0010,     /* finalni trida */
    ACC_SUPER      = 0x0020,     /* semantika instrukce invokespecial */
    ACC_INTERFACE  = 0x0200,     /* rozliseni trida/rozhrani */
    ACC_ABSTRACT   = 0x0400,     /* abstraktni trida */
    ACC_SYNTHETIC  = 0x1000,     /* synteticka trida */
    ACC_ANNOTATION = 0x2000,     /* anotace */
    ACC_ENUM       = 0x4000,     /* vycet */
};

Tyto konstanty jsou použity v nové funkci process_class_flag­s:

/*
 * Nacteni a vypis atributu tridy ci rozhrani.
 */
void process_class_flags(FILE *fin)
{
    uint16_t flags;

    flags = read_two_bytes(fin);
    printf("\nClass/interface attributes: 0x%04x\n", flags);

    if (flags & ACC_PUBLIC)     puts("    ACC_PUBLIC");
    if (flags & ACC_FINAL)      puts("    ACC_FINAL");
    if (flags & ACC_SUPER)      puts("    ACC_SUPER");
    if (flags & ACC_INTERFACE)  puts("    ACC_INTERFACE");
    if (flags & ACC_ABSTRACT)   puts("    ACC_ABSTRACT");
    if (flags & ACC_SYNTHETIC)  puts("    ACC_SYNTHETIC");
    if (flags & ACC_ANNOTATION) puts("    ACC_ANNOTATION");
    if (flags & ACC_ENUM)       puts("    ACC_ENUM");
}

Zdrojový text tímto způsobem upraveného dekompileru souborů .class můžete nalézt zde, popř. si můžete prohlédnout i zdrojový kód se zvýrazněnou syntaxí.

Ukažme si nyní výpis příznaků pro standardní .class soubory získané z archivu rt.jar, který většinou můžete nalézt v adresáři /usr/lib/jvm/ja­va***/jre/lib. Připomeňme si, že v archivu rt.jar se nachází všechny třídy tvořící standardní API Javy:

java.lang.Object:

Class/interface attributes: 0x0021
    ACC_PUBLIC
    ACC_SUPER

java.lang.String:

Class/interface attributes: 0x0031
    ACC_PUBLIC
    ACC_FINAL
    ACC_SUPER

java.lang.Number:

Class/interface attributes: 0x0421
    ACC_PUBLIC
    ACC_SUPER
    ACC_ABSTRACT

java.lang.Inte­ger:

Class/interface attributes: 0x0031
    ACC_PUBLIC
    ACC_FINAL
    ACC_SUPER

java.lang.Com­parable:

Class/interface attributes: 0x0601
    ACC_PUBLIC
    ACC_INTERFACE
    ACC_ABSTRACT

java.lang.Ove­rride:

Class/interface attributes: 0x2601
    ACC_PUBLIC
    ACC_INTERFACE
    ACC_ABSTRACT
    ACC_ANNOTATION

java.lang.Excep­tion:

Class/interface attributes: 0x0021
    ACC_PUBLIC
    ACC_SUPER

java.lang.NullPo­interException:

Class/interface attributes: 0x0021
    ACC_PUBLIC
    ACC_SUPER

java.lang.Class:

Class/interface attributes: 0x0031
    ACC_PUBLIC
    ACC_FINAL
    ACC_SUPER

4. Jméno třídy/rozhraní/výč­tu/anotace a jméno nadřazené třídy

Ihned za dvojicí bajtů, v nichž jsou uloženy příznaky třídy, výčtu, rozhraní či anotace, se nachází další důležitý údaj. Tento údaj reprezentuje jméno třídy, rozhraní, anotace či výčtu, ke které přísluší daný soubor .class. Ve skutečnosti však na tomto místě bajtkódu není uložen přímo řetězec s názvem příslušného jazykového prvku, ale pouze dvoubajtový odkaz na záznam umístěný v constant poolu. Musí se přitom vždy jednat o odkaz na záznam typu CONSTANT_Class, což je samozřejmě náležitě kontrolováno již při načítání bajtkódu do virtuálního stroje Javy. Připomeňme si, že záznam typu CONSTANT_Class obsahuje odkaz (index) na záznam typu CONSTANT_Utf8, který již obsahuje kýženou řetězcovou konstantu (literál) se jménem třídy. Poznamenejme, že jméno třídy je uvedeno v plné podobě, tj. i se jménem balíčku, v němž se třída nachází. Pro oddělení jednotlivých částí „cesty“ ke třídě je použit znak lomítka, který lze pro účely tisku změnit na znak tečky.

Velmi podobný význam má i další dvojice bajtů uložená v bajtkódu. Tento údaj obsahuje informaci o jménu nadřazené třídy (super class) a opět se musí jednat o index do constant poolu, jenž odkazuje na záznam typu CONSTANT_Class (není snad nutné připomínat, že při načítání bajtkódu je jeho korektnost opět kontrolována). Mezi oběma zmíněnými názvy je však jeden rozdíl – zatímco název třídy musí být vždy korektně vyplněn, v případě názvu nadřazené třídy je možné, aby tento údaj obsahoval nulu, ovšem pouze v tom speciálním případě, že bajtkód byl získán překladem třídy Object, která nemá žádnou nadtřídu, což vyplývá ze samotné specifikace programovacího jazyka Java. Ostatní třídy, včetně tříd bez explicitně specifikované nadtřídy, mají tento údaj vyplněn.

5. Jména tříd a nadřazených tříd u vybraných souborů .class pocházejících z balíčku java.lang

Úprava našeho demonstračního dekompileru bajtkódu takovým způsobem, aby dokázal zobrazit jméno třídy (atributu, výčtu…) a jméno příslušné nadtřídy, není vůbec složitá, neboť postačuje načíst obě dvojice bajtů a následně je použít jako indexy do constant poolu, jehož obsah je uložen v poli pool_entries. Funkce pro výpis jména třídy (či jiného jazykového prvku) vypadá následovně:

/*
 * Nacteni a vypis jmena tridy.
 */
void process_class_name(FILE *fin)
{
    /* nacist index z bajtkodu */
    uint16_t index = read_two_bytes(fin);

    /* v cecku se indexuje od 0, v constant poolu od 1 */
    index--;

    printf("\nClass name is stored in constant pool #%d\n", index);

    PoolEntry pool_entry = pool_entries[index];
    print_class_info(&pool_entry);
}

Výpis jména nadřazené třídy je nepatrně složitější, neboť je zapotřebí detekovat speciální případ třídy Object:

/*
 * Nacteni a vypis jmena nadrazene tridy.
 */
void process_superclass_name(FILE *fin)
{
    /* nacist index z bajtkodu */
    uint16_t index = read_two_bytes(fin);

    /* test na specialni pripad */
    if (index == 0)
    {
        printf("\nIt's a class without super class!\n");
    }
    else
    {
        /* v cecku se indexuje od 0, v constant poolu od 1 */
        index--;

        printf("\nSuper class name is stored in constant pool #%d\n", index);
        PoolEntry pool_entry = pool_entries[index];
        print_class_info(&pool_entry);
    }
}

Zdrojový text třetí verze demonstračního dekompileru souborů .class můžete nalézt zde, popř. si můžete prohlédnout i zdrojový kód se zvýrazněnou syntaxí.

Opět si můžeme vyzkoušet, jaké údaje získáme analýzou .class souborů ze standardního balíčku java.lang:

java.lang.Object:

Class name is stored in constant pool #17
Class            74        java/lang/Object
It's a class without super class!

java.lang.String:

Class name is stored in constant pool #39
Class           414        java/lang/String
Super class name is stored in constant pool #116
Class           493        java/lang/Object

java.lang.Number:

Class name is stored in constant pool #2
Class            34        java/lang/Number
Super class name is stored in constant pool #3
Class            35        java/lang/Object

java.lang.Inte­ger:

Class name is stored in constant pool #32
Class           231        java/lang/Integer
Super class name is stored in constant pool #69
Class           258        java/lang/Number

java.lang.Com­parable:

Class name is stored in constant pool #0
Class            10        java/lang/Comparable
Super class name is stored in constant pool #1
Class            11        java/lang/Object

java.lang.Ove­rride:

Class name is stored in constant pool #0
Class            14        java/lang/Override
Super class name is stored in constant pool #1
Class            15        java/lang/Object

java.lang.Excep­tion:

Class name is stored in constant pool #4
Class            32        java/lang/Exception
Super class name is stored in constant pool #5
Class            33        java/lang/Throwable

java.lang.NullPo­interException:

Class name is stored in constant pool #2
Class            19        java/lang/NullPointerException
Super class name is stored in constant pool #3
Class            20        java/lang/RuntimeException

java.lang.Class:

Class name is stored in constant pool #26
Class           681        java/lang/Class
Super class name is stored in constant pool #237
Class           882        java/lang/Object

Pokud pro jednoduchost nebudeme brát do úvahy implementovaná rozhraní, lze celou objektovou hierarchii všech tříd zrekonstruovat pomocí dvojice údajů popsaných v předchozích odstavcích.

6. Seznam implementovaných rozhraní

Z informací, které jsme až doposud z bajtkódu získali, je již možné částečně zrekonstruovat hlavičku libovolné třídy, protože již známe její příznaky (public, abstract, final atd.) a samozřejmě i její plné jméno i jméno nadřazené třídy (včetně uvedení balíčku). Ovšem ve skutečnosti může třída implementovat i libovolný počet rozhraní, což je další informace, kterou je nutné nějakým způsobem přečíst z bajtkódu. To je ve skutečnosti velmi jednoduché, neboť ihned za dvojicí indexů odkazujících na jméno třídy a nadřazené třídy se v bajtkódu nachází šestnáctibitové slovo s počtem všech implementovaných rozhraní (čistě teoreticky jich tedy může být až 65535) a ihned za tímto údajem se nachází n šestnáctibitových indexů do constant poolu, kde n odpovídá počtu implementovaných rozhraní (toto pole indexů může samozřejmě být i prázdné, pokud třída žádné rozhraní neimplementuje, tj. n==0). Podobně jako u jména třídy i jména nadtřídy, musí každý index v poli s rozhraními odkazovat na záznam typu CONSTANT_Class, který sám obsahuje odkaz na záznam typu CONSTANT_Utf8, tj. na vlastní řetězec se jménem rozhraní.

7. (Prozatím) finální verze dekompileru souborů .class – doplnění o výpis všech implementovaných rozhraní

Doplnění našeho demonstračního dekompileru bajtkódu o výpis všech implementovaných rozhraní je obstaráno funkcí process_all_im­plemented_inter­faces(), kterou je nutné zavolat ihned po funkci process_super­class_name() (přesněji řečeno se nemusí tyto funkce volat ihned po sobě, mezi voláním těchto funkcí však nesmí dojít ke čtení údajů z bajtkódu, protože by došlo k posunu interně udržovaného offsetu posledně načteného bajtu). Funkce process_all_im­plemented_inter­faces je velmi jednoduchá – pouze přečte počet indexů v tabulce implementovaných rozhraní a posléze celou tabulku zpracuje a vytiskne příslušné referencované hodnoty získané z constant poolu:

/*
 * Nacteni a vypis vsech implementovanych rozhrani
 */
void process_all_implemented_interfaces(FILE *fin)
{
    int i;
    /* nacist pocet implementovanych rozhrani */
    uint16_t interfaces = read_two_bytes(fin);
    /* zakladni informace pro uzivatele */
    printf("\nNumber of implemented interfaces: %d\n", interfaces);

    /* vypis vsech rozhrani */
    for (i = 0; i < interfaces; i++)
    {
        /* nacist index do constant poolu */
        int index = read_two_bytes(fin);
        /* v cecku se indexuje od 0, v constant poolu od 1 */
        index--;
        /* ziskat a vypsat pozadovanou informaci */
        PoolEntry pool_entry = pool_entries[index];
        print_class_info(&pool_entry);
        putchar('\n');
    }
}

Zdrojový text již čtvrté varianty dekompileru souborů .class můžete nalézt zde, popř. si můžete prohlédnout i zdrojový kód se zvýrazněnou syntaxí.

8. Výpis všech implementovaných rozhraní u vybraných souborů .class pocházejících z balíčku java.lang

S využitím prozatím finální verze demonstračního dekompileru bajtkódu je možné snadno zjistit seznam všech rozhraní implementovaných vybranými třídami ze standardního balíčku java.lang:

java.lang.Object:

Number of implemented interfaces: 0

java.lang.String:

Number of implemented interfaces: 3
Class           494        java/io/Serializable
Class           495        java/lang/Comparable
Class           496        java/lang/CharSequence

java.lang.Number:

Number of implemented interfaces: 1
Class            36        java/io/Serializable

java.lang.Inte­ger:

Number of implemented interfaces: 1
Class           259        java/lang/Comparable

java.lang.Com­parable:

Number of implemented interfaces: 0

java.lang.Ove­rride:

Number of implemented interfaces: 1
Class            16        java/lang/annotation/Annotation

java.lang.Excep­tion:

Number of implemented interfaces: 0

java.lang.NullPo­interException:

Number of implemented interfaces: 0

java.lang.Class:

Number of implemented interfaces: 4
Class           923        java/io/Serializable
Class           924        java/lang/reflect/GenericDeclaration
Class           925        java/lang/reflect/Type
Class           926        java/lang/reflect/AnnotatedElement

9. Odkazy na Internetu

  1. The JavaTM Virtual Machine Specification, Second Edition
    http://java.sun­.com/docs/book­s/jvms/second_e­dition/html/VMSp­ecTOC.doc.html
  2. The class File Format
    http://java.sun­.com/docs/book­s/jvms/second_e­dition/html/Clas­sFile.doc.html
  3. javap – The Java Class File Disassembler
    http://docs.o­racle.com/java­se/1.4.2/docs/to­oldocs/window­s/javap.html
  4. javap-java-1.6.0-openjdk(1) – Linux man page
    http://linux.di­e.net/man/1/j­avap-java-1.6.0-openjdk
  5. Using javap
    http://www.ide­velopment.info/da­ta/Programmin­g/java/miscella­neous_java/Usin­g_javap.html
  6. Examine class files with the javap command
    http://www.techre­public.com/ar­ticle/examine-class-files-with-the-javap-command/5815354
  7. BCEL Home page
    http://common­s.apache.org/bcel/
  8. BCEL Manual
    http://common­s.apache.org/bcel/ma­nual.html
  9. Byte Code Engineering Library (Wikipedia)
    http://en.wiki­pedia.org/wiki/BCEL
  10. Java programming dynamics, Part 7: Bytecode engineering with BCEL
    http://www.ib­m.com/developer­works/java/li­brary/j-dyn0414/
  11. Bytecode Engineering
    http://book.chi­naunix.net/spe­cial/ebook/Co­re_Java2_Volu­me2AF/0131118269/ch13lev­1sec6.html
  12. BCEL Tutorial
    http://www.smfsup­port.com/suppor­t/java/bcel-tutorial!/
  13. ASM Home page
    http://asm.ow2­.org/
  14. Seznam nástrojů využívajících projekt ASM
    http://asm.ow2­.org/users.html
  15. ObjectWeb ASM (Wikipedia)
    http://en.wiki­pedia.org/wiki/Ob­jectWeb_ASM
  16. Java Bytecode BCEL vs ASM
    http://james.o­negoodcookie.com/2005/10­/26/java-bytecode-bcel-vs-asm/
  17. Bytecode Outline plugin for Eclipse (screenshoty + info)
    http://asm.ow2­.org/eclipse/in­dex.html
  18. aspectj (Eclipse)
    http://www.eclip­se.org/aspectj/
  19. Aspect-oriented programming (Wikipedia)
    http://en.wiki­pedia.org/wiki/As­pect_oriented_pro­gramming
  20. AspectJ (Wikipedia)
    http://en.wiki­pedia.org/wiki/As­pectJ
  21. EMMA: a free Java code coverage tool
    http://emma.sou­rceforge.net/
  22. Cobertura
    http://cobertu­ra.sourceforge­.net/
  23. FindBugs
    http://findbug­s.sourceforge­.net/
  24. GNU Classpath
    www.gnu.org/s/clas­spath/
  25. Java VMs Compared
    http://bugblog­ger.com/java-vms-compared-160/
  26. JSRs: Java Specification Requests – JSR 223: Scripting for the Java Platform
    http://www.jcp­.org/en/jsr/de­tail?id=223
  27. Scripting for the Java Platform
    http://java.sun­.com/developer/techni­calArticles/J2SE/Des­ktop/scriptin­g/
  28. Scripting for the Java Platform (Wikipedia)
    http://en.wiki­pedia.org/wiki/Scrip­ting_for_the_Ja­va_Platform
  29. Java Community Process
    http://en.wiki­pedia.org/wiki/Ja­va_Specificati­on_Request
  30. Java HotSpot VM Options
    http://www.ora­cle.com/technet­work/java/java­se/tech/vmopti­ons-jsp-140102.html
  31. Great Computer Language Shootout
    http://c2.com/cgi/wi­ki?GreatCompu­terLanguageSho­otout
  32. Java performance
    http://en.wiki­pedia.org/wiki/Ja­va_performance
  33. Trying the prototype
    http://mail.o­penjdk.java.net/pi­permail/lambda-dev/2010-August/002179.html
  34. Better closures (for Java)
    http://blogs.sun­.com/jrose/en­try/better_clo­sures
  35. Lambdas in Java: An In-Depth Analysis
    http://www.in­foq.com/articles/lam­bdas-java-analysis
  36. Class ReflectiveOpe­rationExcepti­on
    http://downlo­ad.java.net/jdk7/doc­s/api/java/lan­g/ReflectiveO­perationExcep­tion.html
  37. Proposal: Indexing access syntax for Lists and Maps
    http://mail.o­penjdk.java.net/pi­permail/coin-dev/2009-March/001108.html
  38. Proposal: Elvis and Other Null-Safe Operators
    http://mail.o­penjdk.java.net/pi­permail/coin-dev/2009-March/000047.html
  39. Java 7 : Oracle pushes a first version of closures
    http://www.bap­tiste-wicht.com/2010/05­/oracle-pushes-a-first-version-of-closures/
  40. Groovy: An agile dynamic language for the Java Platform
    http://groovy­.codehaus.org/O­perators
  41. Better Strategies for Null Handling in Java
    http://www.sli­deshare.net/Step­han.Schmidt/bet­ter-strategies-for-null-handling-in-java
  42. Control Flow in the Java Virtual Machine
    http://www.ar­tima.com/under­thehood/flowP­.html
  43. Java Virtual Machine
    http://en.wiki­pedia.org/wiki/Ja­va_virtual_machi­ne
  44. ==, .equals(), compareTo(), and compare()
    http://leepoin­t.net/notes-java/data/expres­sions/22compa­reobjects.html
  45. New JDK7 features
    http://openjdk­.java.net/pro­jects/jdk7/fe­atures/
  46. Project Coin: Bringing it to a Close(able)
    http://blogs.sun­.com/darcy/en­try/project_co­in_bring_close
  47. CloseableFinder source code
    http://blogs.sun­.com/darcy/re­source/Projec­tCoin/Closeable­Finder.java
  48. Joe Darcy blog about JDK
    http://blogs.sun­.com/darcy
  49. Java 7 – more dynamics
    http://www.bap­tiste-wicht.com/2010/04­/java-7-more-dynamics/
Našli jste v článku chybu?

4. 1. 2012 3:27

Jardik (neregistrovaný)

Prohlašuju se za blba.

Každopádně nadále budu používat správné formáty a nebudu funkci printf lhát. A pokud není někde standardem garantováno, že sizeof(uint16_t) < sizeof(int) (jakože já ho nikdy nečetl, ale vy ho třeba umíte zpaměti), tak je stejně 'nutné' ho použít.

3. 1. 2012 21:06

IT (neregistrovaný)

C99, 6.3.1.1.2

The following may be used in an expression wherever an int or unsigned int may be used:

-- An object or expression with an integer type whose integer conversion rank is less than the rank of int and unsigned int.
-- A bit-field of type _Bool, int, signed int, or unsigned int.

If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. All other types are unchan…


Lupa.cz: Kdo pochopí vtip, může jít do ČT vyvíjet weby

Kdo pochopí vtip, může jít do ČT vyvíjet weby

Podnikatel.cz: K EET. Štamgast už peníze na stole nenechá

K EET. Štamgast už peníze na stole nenechá

Podnikatel.cz: Změny v cestovních náhradách 2017

Změny v cestovních náhradách 2017

120na80.cz: 5 nejčastějších mýtů o kondomech

5 nejčastějších mýtů o kondomech

DigiZone.cz: TV Philips a Android verze 6.0

TV Philips a Android verze 6.0

Podnikatel.cz: Chtějte údaje k dani z nemovitostí do mailu

Chtějte údaje k dani z nemovitostí do mailu

Lupa.cz: Insolvenční řízení kvůli cookies? Vítejte v ČR

Insolvenční řízení kvůli cookies? Vítejte v ČR

120na80.cz: Pánové, pečujte o svoje přirození a prostatu

Pánové, pečujte o svoje přirození a prostatu

120na80.cz: Horní cesty dýchací. Zkuste fytofarmaka

Horní cesty dýchací. Zkuste fytofarmaka

Lupa.cz: Teletext je „internetem hipsterů“

Teletext je „internetem hipsterů“

Měšec.cz: U levneELEKTRO.cz už reklamaci nevyřídíte

U levneELEKTRO.cz už reklamaci nevyřídíte

Vitalia.cz: Mondelez stahuje rizikovou čokoládu Milka

Mondelez stahuje rizikovou čokoládu Milka

Měšec.cz: Jak vymáhat výživné zadarmo?

Jak vymáhat výživné zadarmo?

Podnikatel.cz: Chaos u EET pokračuje. Jsou tu další návrhy

Chaos u EET pokračuje. Jsou tu další návrhy

Vitalia.cz: Spor o mortadelu: podle Lidlu falšovaná nebyla

Spor o mortadelu: podle Lidlu falšovaná nebyla

Vitalia.cz: Proč vás každý zubař posílá na dentální hygienu

Proč vás každý zubař posílá na dentální hygienu

Root.cz: Certifikáty zadarmo jsou horší než za peníze?

Certifikáty zadarmo jsou horší než za peníze?

Měšec.cz: Jak levně odeslat balík přímo z domu?

Jak levně odeslat balík přímo z domu?

Vitalia.cz: Taky věříte na pravidlo 5 sekund?

Taky věříte na pravidlo 5 sekund?

Měšec.cz: Air Bank zruší TOP3 garanci a zdražuje kurzy

Air Bank zruší TOP3 garanci a zdražuje kurzy