Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: Natix 14. 09. 2012, 23:42:13

Název: K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Natix 14. 09. 2012, 23:42:13
Zdravím,

vím, že stringové literály jsou v Javě internované.
Vím, že ("" == "") je true, ale že (new String() == "") je false.
Taky vím, že string získaný voláním subString sdílí své char pole s původním stringem, což může způsobit memory leak, pokud vyrábím z hodně velkého stringu malinký substring, takže je v takovém případě potřeba volat kopírovací konstrutor new String(String).

Ale nedokážu přijít na žádný use case pro defaultní konstruktor new String(). Nenapadá mě situace, kdy bych potřeboval mít prázdný string, který nebude identický s tím, který je internovaný v poolu.

Že by nějaké obskurní použití v IdentityHashMap, WeakHashMap nebo něčem podobném? Nebo tu prostě žádný důvod není a holt v Javě 1.0 ten konstruktor jednou dali public, tak tu bude už navždycky strašit? Tuší někdo?
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Zdenek 14. 09. 2012, 23:50:25
 /**
  144        * Initializes a newly created {@code String} object so that it represents
  145        * an empty character sequence.  Note that use of this constructor is
  146        * unnecessary since Strings are immutable.
  147        */
  148       public String() {
  149           this.offset = 0;
  150           this.count = 0;
  151           this.value = new char[0];
  152       }
  153   

asi nanic, sami to priznavaji v javadoc String() constructoru :)
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: klw 15. 09. 2012, 10:48:29
Asi je tam pro úplnost, dovedu si představit třeba nějaký fašizující use case, kdy by "" bylo třeba nahradit new String(), aby bylo zřejmé, že se nejedná o magický řetězec, a zároveň by nebylo chtěné mít "" jako konstantu. Sice by to asi nebylo nikterak efektivní, ale v praxi je možné vidět všechno...

Nebo tu prostě žádný důvod není a holt v Javě 1.0 ten konstruktor jednou dali public, tak tu bude už navždycky strašit?
Tohle je každopádně vysoce pravděpodobné, kvůli zachování kompatibility se na API zanechávají všelijaké obskurní metody. Špatně napsané metody a třídy se sice označují jako deprecated, nicméně to zde není třeba, neboť konstruktor dělá přesně to, co má ;-)
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: klw 15. 09. 2012, 10:57:27
A ještě mě napadá použití v testech, např. pro testování jedinečnosti klíčů, nebo něco v tom smyslu, kdy by bylo třeba pracovat právě s tímto předpokladem:

Vím, že ("" == "") je true, ale že (new String() == "") je false.

Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: kuka 15. 09. 2012, 11:01:42
Ten konstruktor je asi stejne smysluplny jako konstruktor s parametrem typu String. Nektere nastroje pouzivajici reflexi to mohou pouzivat, napriklad vytvareji defualtni hodnotu cehokoliv volanim defaultniho konstruktoru, tzn. trida bez nej muze byt pro ne problem. Normalni clovek to kazdopadne nikdy nepouzije. Pri zmenach API javy je snaha minimalizovat dopad na existujici kod, takze proc by se mel odstranovat konstruktor, ktery funguje zcela spravne? Aby nestrasil? Mne nestrasi a ani neznam nikoho, koho by strasil:-)
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Lenin POWER! 15. 09. 2012, 11:03:34
kvuli deserializaci
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Rax 15. 09. 2012, 11:13:49
Ale nedokážu přijít na žádný use case pro defaultní konstruktor new String().

Je tam zásadní chyba v implementaci operátoru == pro String, nikoliv v existenci konstruktoru, to je celé, porovnávají se pointery na instanci, nikoliv stringy samotné. Správně by (new String() == "") vracelo true, ale soudruzi si řekli ne, my to uděláme špatně.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: kuka 15. 09. 2012, 12:27:20
Ale nedokážu přijít na žádný use case pro defaultní konstruktor new String().

Je tam zásadní chyba v implementaci operátoru == pro String, nikoliv v existenci konstruktoru, to je celé, porovnávají se pointery na instanci, nikoliv stringy samotné. Správně by (new String() == "") vracelo true, ale soudruzi si řekli ne, my to uděláme špatně.

To jsou vsechno veci vychazejici ze specifikace - == porovnava instance, new musi vzdy vytvorit novou instanci. Bylo by opravdu chytre mit uplne jine chovani techto zakladnich veci pro String a pro ostatni tridy. A cilem by bylo co? Aby mohl nekdo napsat ptakovinu typu  (new String() == "") a mit z toho true...
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Rax 15. 09. 2012, 12:40:24
A cilem by bylo co?

Nic než větší přehlednost kódu. Současný stav je nepřehledný, což dokazuje vznik tohoto tématu.
new String() == "" by fungovalo stejně jako 1 == 1
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Pavel Tisnovsky 15. 09. 2012, 12:49:16
Ten problem (resp. nejasnosti okolo ==) vyplyva z toho, ze retezce jsou v Jave na jakemsi pomezi mezi primitivnimi datovymi typy, pro nez existuje spouta operatoru a na druhe strane je to normalni objekt. Samozrejme si tvurci Javy uvedomovali, ze retezce jsou dost zakladni soucast jazyka, takze jsou to sice objekty, ovsem existuji pro ne dve specialni jazykove konstrukce - retezcovy literal typy "hello world" a operator +, ktery se interne preklada jako volani metody. Nicmene uz operator == ma chovani stejne jako pro ostatni objekty, tj. porovnava reference, coz vede ke spatne odhalitelnym chybam, zejmena u lidi, co na Javu prejdou z jinych jazyku. Podle me se mel uz na zacatku pridat operator === ktery by interne byl prekladan na == pro primitivni typy a na .equals pro objektove typy, ale holt to v Jave neni, takze je kod ukecanejsi, nez bych si osobne predstavoval.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Rax 15. 09. 2012, 12:55:57
Nicmene uz operator == ma chovani stejne jako pro ostatni objekty, tj. porovnava reference, coz vede ke spatne odhalitelnym chybam, zejmena u lidi, co na Javu prejdou z jinych jazyku.

Chyba se udělala už tehdy, když se operátor == pro objekty udělal blbě na porovnávání pointerů na instanci a ne na porovnávání obsahů instancí, tak jak by se normální člověk dle selského rozumu domníval podle chování 1 == 1. V dnešním stavu máme jeden operátor s dvěma různými chováními a to nutně muselo skončit průšvihem.
Vyřešit už to patrně nepůjde, není to bug ale feature.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Natix 15. 09. 2012, 12:58:55
Pokud jde o == vs. equals, tak tohle je taky dobrá sranda:
Kód: [Vybrat]
Long x = 5L;
Long y = 5L;
System.out.println(x == y); // true

Long a = 1000L;
Long b = 1000L;
System.out.println(a == b); // false

Ale o tomhle jsem se bavit nechtěl.

kvuli deserializaci

Je možné rozvést?
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: kuka 15. 09. 2012, 13:57:57
Chyba se udělala už tehdy, když se operátor == pro objekty udělal blbě na porovnávání pointerů na instanci a ne na porovnávání obsahů instancí, tak jak by se normální člověk dle selského rozumu domníval podle chování 1 == 1. V dnešním stavu máme jeden operátor s dvěma různými chováními a to nutně muselo skončit průšvihem.

To je castecne dusledek samotne existence primitivnich datovych typu. Jazyk by byl peknejsi, kdyby v nem vubec nebyly, ale zase by se nedaly nektere veci naprogramovat tak efektivne. Asi by bylo hezci, kdyby se napriklad == prekladalo na equals a pro porovnani "pointeru" by byl jiny operator, ale dopady se prehaneji, viz "to nutně muselo skončit průšvihem". Osobně jsem chybu související s tímto "problémem" myslím nikdy neudělal a v práci jsem ji viděl naposledy před několika lety u naprostého začátečníka - začátečníci ale dělají i spousty dalších chyb. Mnohem víc mi chybí třeba elvis operátory.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Lenin POWER! 15. 09. 2012, 14:54:29
kvuli deserializaci
Je možné rozvést?

Porno umis na netu najit sam nebo ti s tim pomaha maminka?
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Natix 15. 09. 2012, 15:16:04
kvuli deserializaci
Je možné rozvést?

Porno umis na netu najit sam nebo ti s tim pomaha maminka?

Ne, natáčíme si vlastní.

Sorry, že jsem si dovolil na diskuzním fóru položit dotaz, to se asi nesmí.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: klw 15. 09. 2012, 16:29:46
kvuli deserializaci
Jenže konstruktor bez argumentů pro deserializaci Serializable objektů není vůbec potřeba.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: alef0 15. 09. 2012, 16:46:58
 serializacia nepotrebuje no-arg konstruktor, to len pri dedicnosti, co ocividne nie je pripad stringu

 http://www.jguru.com/faq/view.jsp?EID=251942

* odchadza tocit Das Java Dämon III. *


Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 15. 09. 2012, 17:08:53
No nevím, přijde mi jako celkem základní věc, že konstruktorem se objekt vytváří v nějakém výchozím stavu na základě parametrů, zatímco při deserializaci se *obnovuje* *jakýkoli* jeho stav ze surových dat. Některé jazyky (Objective C) mají to konstruování ještě explicitnější - operace alloc (alokace paměti - provede se jednou) a init (inicializace stavu - může se provést teoreticky i víckrát nad stejným objektem).

Takže Lenin buď vidí do nějakých souvislostí, které jsou nám smrtelníkům utajeny, nebo prostě zase plácá. Což si může dovolit, protože - jak jsme již mnohokráte byli informování - on sockou nelítá - a o to jde.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: klw 15. 09. 2012, 17:36:04
No nevím, přijde mi jako celkem základní věc, že konstruktorem se objekt vytváří v nějakém výchozím stavu na základě parametrů, zatímco při deserializaci se *obnovuje* *jakýkoli* jeho stav ze surových dat. Některé jazyky (Objective C) mají to konstruování ještě explicitnější - operace alloc (alokace paměti - provede se jednou) a init (inicializace stavu - může se provést teoreticky i víckrát nad stejným objektem).

Takže Lenin buď vidí do nějakých souvislostí, které jsou nám smrtelníkům utajeny, nebo prostě zase plácá. Což si může dovolit, protože - jak jsme již mnohokráte byli informování - on sockou nelítá - a o to jde.

Plácá, viz jednoduchý příklad s vlastním objektem, na kterém je zřejmé, že při deserializaci se konstruktor nepoužije:
Kód: [Vybrat]
public class MyClass implements Serializable {

  private int value;

  private MyClass() {
    value = 1;
  }

  public MyClass(String value) {
    this.value = Integer.valueOf(value) * 2;
  }

  public int getA() {
    return value;
  }

  public void setA(int a) {
    this.value = a;
  }
}

public class Main {

  public static void main(String[] args) throws Exception {
    MyClass myClass1 = new MyClass("10");

    FileOutputStream fileOut = new FileOutputStream("myclass.ser");
    ObjectOutputStream out = new ObjectOutputStream(fileOut);
    out.writeObject(myClass1);
    out.close();
    fileOut.close();

    System.out.println("myClass1: " + myClass1.getA());

    MyClass myClass2 = null;
    FileInputStream fileIn = new FileInputStream("myclass.ser");
    ObjectInputStream in = new ObjectInputStream(fileIn);
    myClass2 = (MyClass) in.readObject();
    in.close();
    fileIn.close();

    System.out.println("myClass2: " + myClass2.getA());
  }
}

Výstup:
Kód: [Vybrat]
myClass1: 20
myClass2: 20
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: alef0@szm.sk 15. 09. 2012, 17:46:55
Nehovoriac o tom, že Stringy sa i tak serializujú špecifickým spôsobom. Serializácia bežne vbuchne do streamu všetky inštančné premenné (a naopak, pri deserializácii ich vyplní zo streamu) ale OpenJDK má vlastný spôsob:

Citace
Class String is special cased within the Serialization Stream Protocol.

A String instance is written initially into an ObjectOutputStream in the
following format:

   TC_STRING (utf String)

The String is written by method `DataOutput.writeUTF`.
A new handle is generated to  refer to all future references to the
string instance within the stream.

---------------

Z iného súdka: ten copy constructor (public String(String s)) má svoj zmysel. Mamička mi našla, že:

http://hanuska.blogspot.com/2006/03/how-useful-is-stringstring-constructor.html

V skratke: ak vrátite z obrovského Stringu maličký substring, tak ten navrátený String stále odkazuje na pôvodné obrovské pole bajtov. V takom prípade je lepšie vyrobiť radšej novú inštanciu cez copy constructor a obrovský String sa môže radostne zgarbagecollectovať.

Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 15. 09. 2012, 17:49:30
V skratke: ak vrátite z obrovského Stringu maličký substring, tak ten navrátený String stále odkazuje na pôvodné obrovské pole bajtov. V takom prípade je lepšie vyrobiť radšej novú inštanciu cez copy constructor a obrovský String sa môže radostne zgarbagecollectovať.
O tom už byla řeč v prvním příspěvku.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: kuka 15. 09. 2012, 18:38:10
Z iného súdka: ten copy constructor (public String(String s)) má svoj zmysel. Mamička mi našla, že:

http://hanuska.blogspot.com/2006/03/how-useful-is-stringstring-constructor.html

V skratke: ak vrátite z obrovského Stringu maličký substring, tak ten navrátený String stále odkazuje na pôvodné obrovské pole bajtov. V takom prípade je lepšie vyrobiť radšej novú inštanciu cez copy constructor a obrovský String sa môže radostne zgarbagecollectovať.

Pokud je opravdu potreba zamezit sdileni bufferu, tak bych "copy constructor" nedoporucoval. Dokumentace API pozadovane chovani nijak nezarucuje (podobne jako nezarucuje sdileni pri substring, to je jen optimalizace). Ze to tak je implementovane v konkretnich zdrojacich (napr OpenJDK) je fajn, ale jinde to muze byt jinak. Pokud je potreba zarucene zamezit sdileni, tak vhodne reseni je treba

new String(s.toCharArray())

ktere jednoduse to kopirovani (chceme kopirovani, kdyz nam vadi sdileni) vynucuje
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: alef0 15. 09. 2012, 18:48:25
Ono je to (viacmenej) povedané v dokumentácii:

Citace
Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since Strings are immutable.

Ale je pravda, že nechce by som byť v situácii, keď zistím, že niekto natvrdo využil toto chovanie v nejakom programe a nezadokumentoval to :-)
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Pavel Tisnovsky 15. 09. 2012, 18:55:45
Chyba se udělala už tehdy, když se operátor == pro objekty udělal blbě na porovnávání pointerů na instanci a ne na porovnávání obsahů instancí, tak jak by se normální člověk dle selského rozumu domníval podle chování 1 == 1. V dnešním stavu máme jeden operátor s dvěma různými chováními a to nutně muselo skončit průšvihem.

To je castecne dusledek samotne existence primitivnich datovych typu. Jazyk by byl peknejsi, kdyby v nem vubec nebyly, ale zase by se nedaly nektere veci naprogramovat tak efektivne. Asi by bylo hezci, kdyby se napriklad == prekladalo na equals a pro porovnani "pointeru" by byl jiny operator, ale dopady se prehaneji, viz "to nutně muselo skončit průšvihem". Osobně jsem chybu související s tímto "problémem" myslím nikdy neudělal a v práci jsem ji viděl naposledy před několika lety u naprostého začátečníka - začátečníci ale dělají i spousty dalších chyb. Mnohem víc mi chybí třeba elvis operátory.

Ja jsem na tu chybu narazil pri oprave programu, kde nekdo udelal (nevim jakym nastrojem, mozna jen rucne) refactoring ve stylu, ze nahradil v nejake metody paramerty foo(int a, int b) za foo(Integer a, Integer b). Ono mu to "magicky" fungovalo diky unboxingu pro prakticky vsechny operatory i prirazeni, ale ouha ve chvili, kdy tam bylo neco na zpusob if (a==b) .... Prekladac s tim kodem byl spokojeny, zadne warningy atd. No prislo se na to relativne rychle, ale i tak...
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Pavel Tisnovsky 15. 09. 2012, 19:02:43
Pokud jde o == vs. equals, tak tohle je taky dobrá sranda:
Kód: [Vybrat]
Long x = 5L;
Long y = 5L;
System.out.println(x == y); // true

Long a = 1000L;
Long b = 1000L;
System.out.println(a == b); // false

Jojo, na to je potreba dat pozor a vedet, jak se vlastne v Jave implementuje autoboxing - zde se vola Long.valueOf() a u nej je jasne napsane, ze NEMUSI vytvaret nove instance Longu, ale muze pouzit hodnoty cachovane. Ktere to jsou, je jiz implementacni detail, coz dela celou situaci jeste horsi :-)
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Lenin POWER! 17. 09. 2012, 01:40:33
1. bultin java serializaci prakticky nikdo nepouziva. Polozme si otazku proc existuje aspon 20 serializacnich frameworku.
2. jednoduchy priklad je z poloviny blbe. Dodelat, souvisi s 1.
3. Prymek, lichoti mi ze mi zavidis letadlo. Vzhledem k tomu ze se odmitas zmenit, tak si nevydelas ani blbech 50 tisic na cessnu 172.

Rekni si, kdyz prachy umi vydelavat i takovej trouba jako lenin, tak ja chytrej kluk to dokazu taky. Je to jednoduchy, jen to vyzaduje uplne jiny zpusob mysleni nez ktery ma 95% populace. Bylo napsano hodne knizek o tom jak se to dela. Precti si nejakou.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: alef0 17. 09. 2012, 01:52:03
A ako to súvisí s prázdnym konštruktorom Stringu?

Ja nechápem, prečo, pán Lenin POWER! ,dokážete jednu informáciu natiahnuť cez dvadsať* arogantných príspevkov s pochybnou kredibilitou, keď stačí napísať "v XStreame na tom stavajú, lebo sa im nechce reflektovať." [teraz trepem]

Dokážete dať aspoň jeden relevantný príklad?

--------
* číslo som vytiahol z brucha rovnako ako počet serializačných frameworkov
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Jakub Galgonek 17. 09. 2012, 03:51:56
new musi vzdy vytvorit novou instanci

Pravda, pravda. Příkaz new vracející referenci na existující instanci by asi nebyl to pravé ořechové (byť to v jiných jazycích jde). Mimochodem:

Kód: [Vybrat]
"Ahoj" == new String("Ahoj")             // false
"Ahoj" == new String("Ahoj").intern()    // true

"" == new String("")                     // false
"" == new String("").intern()            // true

"" == new String()                       // false
"" == new String().intern()              // true
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 17. 09. 2012, 08:50:53
1. bultin java serializaci prakticky nikdo nepouziva. Polozme si otazku proc existuje aspon 20 serializacnich frameworku.
Položme si zajímavější otázku: když built-in serializace prázdný konstruktor nepotřebuje, k čemu ho nutně potřebují ty frameworky?

3. Prymek, lichoti mi ze mi zavidis letadlo. Vzhledem k tomu ze se odmitas zmenit, tak si nevydelas ani blbech 50 tisic na cessnu 172.

Rekni si, kdyz prachy umi vydelavat i takovej trouba jako lenin, tak ja chytrej kluk to dokazu taky. Je to jednoduchy, jen to vyzaduje uplne jiny zpusob mysleni nez ktery ma 95% populace. Bylo napsano hodne knizek o tom jak se to dela. Precti si nejakou.
Ty máš asi pořád pocit, že ti všichni všechno závidí :) Jestli to potřebuješ k nějaké svojí osobnostní integritě, nemám problém tě podpořit: já ti tak závidím ty letadla!


Rekni si, kdyz prachy umi vydelavat i takovej trouba jako lenin, tak ja chytrej kluk to dokazu taky. Je to jednoduchy, jen to vyzaduje uplne jiny zpusob mysleni nez ktery ma 95% populace. Bylo napsano hodne knizek o tom jak se to dela. Precti si nejakou.
Přečetl jsem si jednu knížku, ve které mě zaujalo tohle:

Citace
Když se rozmnožuje jmění, množí se i příživníci. Jaký prospěch z toho mívá vlastník? Ledaže se na to může dívat.
Sladký je spánek toho, kdo pracuje, ať jí málo nebo mnoho, ale boháčovi nedopřeje spánku sytost.
Je zlý neduh, který jsem pod sluncem viděl: vlastníkovi je ke zlému bohatství, jež střeží.
Po úmorné lopotě může o bohatství přijít a syn, jehož zplodil, stojí s prázdnou rukou.
Jako vyšel z života své matky, nahý zase odchází, jak přišel, a za svoje pachtění si nic neodnese, ani co by se do ruky vešlo.
A také to je zlý neduh: Každý odejde, jak přišel; jaký užitek má z toho, že se pachtil a honil vítr?
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: někdo 17. 09. 2012, 11:31:43
1. bultin java serializaci prakticky nikdo nepouziva. Polozme si otazku proc existuje aspon 20 serializacnich frameworku.

Když otázka, tak s odpovědí: Ve starších verzích Javy byla nativní serializace pomalá, proto vznikla spousta alternativních serializačních frameworků. Java 6 už má ovšem nativní serializaci tak rychlou že používání těch proprietárních frameworků ztrácí význam.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: někdo 17. 09. 2012, 11:39:39
1. bultin java serializaci prakticky nikdo nepouziva. Polozme si otazku proc existuje aspon 20 serializacnich frameworku.
Položme si zajímavější otázku: když built-in serializace prázdný konstruktor nepotřebuje, k čemu ho nutně potřebují ty frameworky?

Built-in serializace podvádí za vydatné podpory JVM. Framework může vytvořit objekt za použití prázdného konstruktoru a pak ho "dodělat" pomocí java.lang.reflect.*.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: alef0 17. 09. 2012, 12:43:18
A čo potom java.lang.Long-y a java.lang.Integer-y?
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: DK 17. 09. 2012, 13:00:41
alef0: Long je delsi, nez Integer, alokuje si vice pameti
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: alef0 17. 09. 2012, 15:14:38
Narážal som na to, že Long nemá verejný bezparametrový konštruktor.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 17. 09. 2012, 16:01:17
Built-in serializace podvádí za vydatné podpory JVM. Framework může vytvořit objekt za použití prázdného konstruktoru a pak ho "dodělat" pomocí java.lang.reflect.*.
To ale není důvod k tomu, aby každý objekt měl povinně bezparametrický konstruktor - a o tom je řeč.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Natix 17. 09. 2012, 16:13:34
Napadlo mě, že smysl tohohle defaultního kontruktoru bude asi podobný jako u jeho obdoby u java.lang.Object.

Vytvořit si instanci obyčejného Objectu samo o sobě nemá moc smysl, leda bych si potřeboval držet privátní objekt, o které vím, že je unikátní. V praxi jsem to viděl aplikované asi jenom pro synchronizační zámek:

Kód: [Vybrat]
private final Object lock = new Object();

Teoreticky by se mohl podobným způsobem definovat také privátní unikátní klíč do IdentityHashMap.

A aby to nebylo tak jednoduché, tak jsou 3 způsoby jak vyrobit prázdný string:
Kód: [Vybrat]
String s = "";
String s = new String();
String s = new String("");
A každý z nich funguje jinak.  :D
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 17. 09. 2012, 16:30:12
Napadlo mě, že smysl tohohle defaultního kontruktoru bude asi podobný jako u jeho obdoby u java.lang.Object.
To těžko - z důvodů, o kterých tady už byla řeč: http://www.jguru.com/faq/view.jsp?EID=34802
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: kuka 17. 09. 2012, 17:47:32
A aby to nebylo tak jednoduché, tak jsou 3 způsoby jak vyrobit prázdný string:
Kód: [Vybrat]
String s = "";
String s = new String();
String s = new String("");
A každý z nich funguje jinak.  :D

Prazdny string jde vytvorit mnohem vice zpusoby. Co to znamena, ze kazdy ze zpusobu funguje jinak? V cm to "neni jednoduche"? A neco z toho vyplyva?
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Natix 17. 09. 2012, 18:08:45
A aby to nebylo tak jednoduché, tak jsou 3 způsoby jak vyrobit prázdný string:
Kód: [Vybrat]
String s = "";
String s = new String();
String s = new String("");
A každý z nich funguje jinak.  :D

Prazdny string jde vytvorit mnohem vice zpusoby. Co to znamena, ze kazdy ze zpusobu funguje jinak? V cm to "neni jednoduche"? A neco z toho vyplyva?

Jo, těch konstruktorů tam je kopec, ale tyhle tři případy výše se liší v principu, (asi) všechny ostatní už jsou obdobné.

Literál "" se bere ze string poolu. Druhý případ vyrobí nový objekt, který má vlastní (nové) interní char pole. Třetí vyrobí nový string objekt, ale bude mít char pole sdílené s prvním. Viz výpis identity-hashcodů:

Kód: [Vybrat]
""
String hashCode: 30223967
char[] hashCode: 18903403

new String()
String hashCode: 14978587
char[] hashCode: 19770577

new String("")
String hashCode: 28117098
char[] hashCode: 18903403
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Lenin POWER! 17. 09. 2012, 23:26:08
1. bultin java serializaci prakticky nikdo nepouziva. Polozme si otazku proc existuje aspon 20 serializacnich frameworku.
Položme si zajímavější otázku: když built-in serializace prázdný konstruktor nepotřebuje, k čemu ho nutně potřebují ty frameworky?

Built-in serializace podvádí za vydatné podpory JVM. Framework může vytvořit objekt za použití prázdného konstruktoru a pak ho "dodělat" pomocí java.lang.reflect.*.

No vidite, tak jste na to prisli. Pokud jde o objekt varianty typu ala Integer, tak ty se diky efektivite serializuji jako primitivni typy a ne jako jejich objekt varianty.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 17. 09. 2012, 23:59:42
No vidite, tak jste na to prisli. Pokud jde o objekt varianty typu ala Integer, tak ty se diky efektivite serializuji jako primitivni typy a ne jako jejich objekt varianty.

Aha, mně to hnedka nedošlo, máš úplnou pravdu! Natix se ptal, proč autoři Javy do API ten konstruktor dali - a ono to bylo takhle:

A: Ty hele, ta naše serializace je zatraceně pomalá!
B: To je v poho, vyrojí se spousta knihoven, který to budou dělat líp.
A: No jo, jenže nebudou potřebovat String()?
B: No, my to obcházíme neveřejnýma funkcema...
A: Tak jim tam ten String() dáme, ať nám tu serializaci můžou udělat pořádně!

Tak to jo.

Stejně to ale museli být pěkní vohnouti, když to vyřešili takhle, místo aby udělali pořádný rozhraní umožňující custom serializaci...

No ale hlavně že to teda už vím a můžu už googlit jenom porno.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Jakub Galgonek 18. 09. 2012, 00:07:11
Framework může vytvořit objekt za použití prázdného konstruktoru a pak ho "dodělat" pomocí java.lang.reflect.*.

Jak konkrétně by se dal dodělat?
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: KapitánRUMFree 18. 09. 2012, 00:18:05
....

-1 bod za naše diskuze o IPv6, ale +10 bodů za tenhle post  ;D
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 18. 09. 2012, 00:25:41
Framework může vytvořit objekt za použití prázdného konstruktoru a pak ho "dodělat" pomocí java.lang.reflect.*.
Jak konkrétně by se dal dodělat?
Nejspíš myslel vytvořit "prázdný" objekt "prázdným" konstruktorem a pak nastavit všechny vlastnosti pomocí java.lang.reflect.Field nebo tak něco...

Tahle myšlenka má jednu drobnou vadu: nemá to absolutně žádnou souvislost s tím, proč má String neparametrický konstruktor. (Nebudeme snad doufám tvrdit, že ho má proto, abysme mohli vytvořit prázdný String a potom ho pomocí reflect.Field změnit...)
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Jakub Galgonek 18. 09. 2012, 00:36:50
Nejspíš myslel vytvořit "prázdný" objekt "prázdným" konstruktorem a pak nastavit všechny vlastnosti pomocí java.lang.reflect.Field nebo tak něco...

No což o to, já vím, jak to myslel. Spíše mne ale zajímá, pokud to jde udělat, tak jak? Hodil by se prostě přiklad kódu.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 18. 09. 2012, 00:43:13
No což o to, já vím, jak to myslel. Spíše mne ale zajímá, pokud to jde udělat, tak jak? Hodil by se prostě přiklad kódu.
No hlavně to nejde udělat u Stringu, takže to je úplně mimo mísu. Stejně pro jakýkoli String obecně musím mít nějaké speciální zacházení, takže nechápu, proč bych to speciální zacházení neměl mít ausgerechnet u prázdnýho Stringu...

Ale už bych se v tom nerejpal, tahle debata je ujetá.

Podle mě to do API dali prostě proto, že to nic nestojí a asi jim to připadalo logciký. A jestli to má nějaký využití? No v hodně mokrých snech asi jo...
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Lenin POWER! 18. 09. 2012, 12:47:00
A: Ty hele, ta naše serializace je zatraceně pomalá!
Deserializace je extremne pomala, java serializace je sice tak o rad pomalejsi nez ostatni frameworky, ale to by se jeste sneslo, ne kazdy projekt hodne serializuje. Vykon je jen jeden z duvodu proc se nepouziva, precti si dokumentaci k nejakemu frameworku co za ostatni problemy se pokousi resit.

Stejně to ale museli být pěkní vohnouti, když to vyřešili takhle, místo aby udělali pořádný rozhraní umožňující custom serializaci...

Je tam Externalizable, ale to se pouziva jeste mene nez Serializable, protoze kdyz si nekdo chce psat custom serializaci tak to napise uz poradne s vyuzitim nejakeho dobreho frameworku, ktery poskytuje vice funkci.

Pro stringy ten vyse zmineny postup funguje. Omez to porno a zacni na sobe makat.

Pro inspiraci nejaky ty frameworky http://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Ondřej Novák 18. 09. 2012, 12:58:51
K puvodni otazce tazatele, k cemu konstruktor bez parametru u stringu. Pokud vim, Java ma generiku a tam je preci jen fajn vedet, ze new E() projde i pro String a nemusim na to vymyslet extraburty.

Skoda ze v C++ to neni jednoznacne. Treba mohu napsat new T() ale funguje to i pro std::string ale kdyz T je treba int, pak hodnota toho objektu je undefined.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: kuka 18. 09. 2012, 14:32:00
K puvodni otazce tazatele, k cemu konstruktor bez parametru u stringu. Pokud vim, Java ma generiku a tam je preci jen fajn vedet, ze new E() projde i pro String a nemusim na to vymyslet extraburty.

Skoda ze v C++ to neni jednoznacne. Treba mohu napsat new T() ale funguje to i pro std::string ale kdyz T je treba int, pak hodnota toho objektu je undefined.

new E()??? A to by podle tebe udelalo co? Za predpokladu, ze by se to vubec prelozilo...
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Natix 18. 09. 2012, 14:50:31
new E() v Javě napsat nejde díky type erasure
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 18. 09. 2012, 15:08:05
No nic, vidím, soudruhu Lenine, že jsi výhrady vůči mimoběžnosti tvého plkání k původní otázce buď nepochopil nebo nevzal v potaz.

Když dovolíš, nemusím na sobě v tomhle ohledu makat, protože v Javě nedělám a dělat nechci. Jednak nejsem primárně programátor, jednak v současnosti používám hlavně Erlang. I ne úplně dobrá znalost Javy stačí na to, aby člověk poznal, jak vaříš z vody.

S dovolením komunikaci s tebou končím, nic mi nedává.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: JanK 18. 09. 2012, 20:37:51
Hlavne: objekty je v Jave nutne porovnavat vzdy pres metodu equals. Tyka se to i typu String.
Prazdny konstruktor s char(0) bych typoval na pozustatek z C++.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Ondřej Novák 19. 09. 2012, 09:35:31
<flame>Aha, koukám, že jsem si myslel o generice v Javě víc, než je schopna. Další důvod, proč Javu nepoužívat</flame>
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: kuka 19. 09. 2012, 09:59:33
<flame>Aha, koukám, že jsem si myslel o generice v Javě víc, než je schopna. Další důvod, proč Javu nepoužívat</flame>

Aha, koukam, ze o generikach v jave nic nevis. Souhlasim, ze je to duvod, proc bys je nemel pouzivat.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 19. 09. 2012, 10:14:01
Aha, koukam, ze o generikach v jave nic nevis. Souhlasim, ze je to duvod, proc bys je nemel pouzivat.
Je to pravda, že generika v javě jsou v podstatě jenom syntaktický cukr - všechno se provádí jenom při překladu a v runtime už je všechno přeložený v podstatě stejně, jako by to bylo v době, kdy ještě generika neexistovala?

To by pak měl Ondra celkem pravdu, že to je nuda...
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Ondřej Novák 19. 09. 2012, 10:34:55

Je to pravda, že generika v javě jsou v podstatě jenom syntaktický cukr - všechno se provádí jenom při překladu a v runtime už je všechno přeložený v podstatě stejně, jako by to bylo v době, kdy ještě generika neexistovala?

To by pak měl Ondra celkem pravdu, že to je nuda...

Mě jen přepkvapuje, že to řešili právě takto. Přitom si myslím, že by neměl být pro překladač problém vygenerovat kód namíru, tak jak to dělá C++ (malé zjednodušení pro ty, kteří nevědí, jak to funguje v C++, tak si představte trochu vymakanější makra v Cčku).

Momentálně by mě třeba zajímalo, jak v Javě řeší generické továrny objektů, když nefunguje new E ... ale to je v celku fuk.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: kuka 19. 09. 2012, 10:51:57
Aha, koukam, ze o generikach v jave nic nevis. Souhlasim, ze je to duvod, proc bys je nemel pouzivat.
Je to pravda, že generika v javě jsou v podstatě jenom syntaktický cukr - všechno se provádí jenom při překladu a v runtime už je všechno přeložený v podstatě stejně, jako by to bylo v době, kdy ještě generika neexistovala?

To by pak měl Ondra celkem pravdu, že to je nuda...

Jestli te zajima, k cemu jsou a jak funguji generika v jave, tak si precti jeden z milionu clanku, ktere o tom existuji. Problem spociva v psani nesmyslu do diskuse k tematu, o kterem dotycny nic nevi (ze konstruktor bez parametru se vyuzije pro generika). At si napise blog "ma predstava o jave, kterou neznam, a jaky ma vztah k C++, ktere znam" a tam se muze zevrubne prozkoumat, proc tu javu udelali tak blbe.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Ondřej Novák 19. 09. 2012, 11:17:21
Jestli te zajima, k cemu jsou a jak funguji generika v jave, tak si precti jeden z milionu clanku, ktere o tom existuji. Problem spociva v psani nesmyslu do diskuse k tematu, o kterem dotycny nic nevi (ze konstruktor bez parametru se vyuzije pro generika). At si napise blog "ma predstava o jave, kterou neznam, a jaky ma vztah k C++, ktere znam" a tam se muze zevrubne prozkoumat, proc tu javu udelali tak blbe.

Bezvadné vyhození z místnosti  :D

Okaj, omlouvám se, netušil jsem, že tohle v Javě nejde. Nicméně pak se nedivím té diskuzi předtím o serializačních frameworcích. Když vidím třeba workaround nemožnosti udělat new na generický typ... doporučení zavolat class.newInstance(), tak ... prominte, musím si odskočit na záchod (chybí tu patřičný smajlík)

Google mi vyplivl taky toto:
http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Constructor.html

kde newInstance volá konstruktor podle parametrů. Předpokládám, že bude volat String() konstruktor, pokud mu tam předložím třídu String a žádné parametry.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: alef0 19. 09. 2012, 11:31:21
Na rozdiel od .NETu, kde sú generiká aj v čase behu, v Jave sa rozhodli to naozaj spraviť v záujme spätnej kompatibility. To má presne dôsledky ako "nemožno spraviť new E", "nemožno sa spýtať, aký typu je prvok List<T>" a podobne, proste všetko je to v čase behu java.lang.Object. Z týchto všetkých vecí ma to až tak neotravuje, asi najdivšia vec bola nemožnosť urobiť pole generických prvkov.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: kuka 19. 09. 2012, 11:49:42
Jestli te zajima, k cemu jsou a jak funguji generika v jave, tak si precti jeden z milionu clanku, ktere o tom existuji. Problem spociva v psani nesmyslu do diskuse k tematu, o kterem dotycny nic nevi (ze konstruktor bez parametru se vyuzije pro generika). At si napise blog "ma predstava o jave, kterou neznam, a jaky ma vztah k C++, ktere znam" a tam se muze zevrubne prozkoumat, proc tu javu udelali tak blbe.

Bezvadné vyhození z místnosti  :D

Okaj, omlouvám se, netušil jsem, že tohle v Javě nejde. Nicméně pak se nedivím té diskuzi předtím o serializačních frameworcích. Když vidím třeba workaround nemožnosti udělat new na generický typ... doporučení zavolat class.newInstance(), tak ... prominte, musím si odskočit na záchod (chybí tu patřičný smajlík)

Google mi vyplivl taky toto:
http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Constructor.html

kde newInstance volá konstruktor podle parametrů. Předpokládám, že bude volat String() konstruktor, pokud mu tam předložím třídu String a žádné parametry.

Nikoho nevyhazuju, na to ani nemam prostredky. Pouze je mym nazorem, ze kdyz necemu nerozumim, tak se k tomu nevyjadruju, nebo si nejprve alespon udelam alespon minimalni prehled. Ty ovsem o generikach v jave vis pouze to, ze se tak jmenuji. Posun na uroven, na ktere by ses mohl smysluplne vyjadrit v teto diskusi by ti pritom zabral maximalne 10 minut.

A k veci. Ano pochopitelne lze pomoci reflexe zavolat kontruktor String() - proc by to nemelo jit? Diskuse byla v podstate o tom, ze pokud stejne musim vedet, ze jde o tridu String a jeji konstruktor bez parametru, a zaroven je zaruceno, ze tento konstruktor musi vratit novou instanci, ktera je obsahove shodna s konstantou prazdny retezec, tak mohu rovnou vratit konstantu prazdny retezec a na volani konstruktoru se vybodnout. Tedy by se zdalo, ze se bez tohoto konstruktoru da obejit a odtud puvodni otazka, proc tam vlastne je. A at uz je duvod jakykoliv, napriklad zjednoduseni pro ruzne, ne nutne pouze serializacni frameworky, jiste tento duvod nijak nesouvisi s generiky.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 19. 09. 2012, 16:57:30
Diskuse byla v podstate o tom, ze pokud stejne musim vedet, ze jde o tridu String a jeji konstruktor bez parametru, a zaroven je zaruceno, ze tento konstruktor musi vratit novou instanci, ktera je obsahove shodna s konstantou prazdny retezec, tak mohu rovnou vratit konstantu prazdny retezec a na volani konstruktoru se vybodnout. Tedy by se zdalo, ze se bez tohoto konstruktoru da obejit a odtud puvodni otazka, proc tam vlastne je.
No výborně. Od odboček jsme se vrátili zpátky k tématu. Přesně kvůli tomuhle, co píšeš, nechápu, proč by ten konstruktor měl být nutný - pro String beztak potřebuju speciální zacházení, takže místo String() tam můžu dát prostě "".
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: kuka 19. 09. 2012, 18:16:52
No výborně. Od odboček jsme se vrátili zpátky k tématu. Přesně kvůli tomuhle, co píšeš, nechápu, proč by ten konstruktor měl být nutný - pro String beztak potřebuju speciální zacházení, takže místo String() tam můžu dát prostě "".

Nikdo netvrdi, ze je ten konstruktor nutny. Na druhou stranu ma rekneme smysluplnou semantiku (zadny vstup = prazdny string), tak proc by tam nemel byt? Pro jine tridy smysluplna semantika neni, tak takovy konstruktor nemaji (napr. BigDecimal). V beznem programu se to smysluplne nepouzije, ale jestli se nekde v existujicim kodu, treba pouzivajicim reflexi, pouziva, tak proc by se to melo necim nahrazovat. Konstruktor proste dela to co ma, vetsina pouziti bude asi chyba (zbytecne vytvarim instanci, kdyz ji nepotrebuju), ale to je chyba spise jen stylu, realny dopad na vykon muze mit pouze ve specifickych pripadech.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Pavel Tisnovsky 19. 09. 2012, 22:46:45
Aha, koukam, ze o generikach v jave nic nevis. Souhlasim, ze je to duvod, proc bys je nemel pouzivat.
Je to pravda, že generika v javě jsou v podstatě jenom syntaktický cukr - všechno se provádí jenom při překladu a v runtime už je všechno přeložený v podstatě stejně, jako by to bylo v době, kdy ještě generika neexistovala?

To by pak měl Ondra celkem pravdu, že to je nuda...

Ano a ne :) Ze signatur metody informace o generikach pri prekladu skutecne "zmizi". Takze napriklad void test1(List) a void test2(List<String>) budou mit shodnou signaturu. Ovsem v bajtkodu se ta informace ve skutecnosti zachova ve forme metadat (nechci tady pouzit slovo atribut, ktere ma bohuzel jiny vyznam v ceskem OOP zargonu), coz si hlida prekladac ve chvili, kdyz se nekde jinde vola mujObjekt.test1() a mujObjekt.test2(). Takze erasure zajisti jednodussi a zpetne kompatibilni volani metod - pamatujme na to, ze Java je novy COBOL :) - a na druhou stranu to zajistuje alespon nejakou typovou bezpecnost.

Co me osobne vadi vice je fakt, ze generika (resp. ty typy) nejsou kovariantni, i kdyz by podle me mohly byt :/
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Pavel Tisnovsky 19. 09. 2012, 22:49:07
Na rozdiel od .NETu, kde sú generiká aj v čase behu, v Jave sa rozhodli to naozaj spraviť v záujme spätnej kompatibility. To má presne dôsledky ako "nemožno spraviť new E", "nemožno sa spýtať, aký typu je prvok List<T>" a podobne, proste všetko je to v čase behu java.lang.Object. Z týchto všetkých vecí ma to až tak neotravuje, asi najdivšia vec bola nemožnosť urobiť pole generických prvkov.

Na druhou stranu je treba diky tomu implementace Clojure pro JVM mnohem snazsi nez v .NET, takze je to neco za neco :)
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 20. 09. 2012, 05:28:47
Ovsem v bajtkodu se ta informace ve skutecnosti zachova ve forme metadat [...], coz si hlida prekladac ve chvili, kdyz se nekde jinde vola mujObjekt.test1() a mujObjekt.test2().
To je zajimava informace - o jaký přesně metadata se jedná? Jak se to správně jmenuje (abych si o tom mohl něco vygooglit)?

A dá se s těmi metadaty nějak softwarově pracovat? Když např. z nějakého zdroje dostanu obecný objekt a chci za běhu zjistit, jakého je typu, můžu nějak zjistit, jestli je to List<X> nebo List<Y>?

A jak je to s tou (obecnou) factory? Když mu předám obecný objekt, dá se vytvořit nová instance? Jde to nějak přibližně takhle?
Citace
Object neznamyObjekt = nepredvidatelnyZdrojObjektu.getNext();
Constructor[]  constructors = neznamyObjekt.getClass().getConstructors();
[...výběr bezparametrického konstruktoru...]
Object neznamyObjekt2 = constructor.newInstance();

Co me osobne vadi vice je fakt, ze generika (resp. ty typy) nejsou kovariantni, i kdyz by podle me mohly byt :/
Jak přesně se tohle projevuje? Že List<X> nemůžu předat někam, kde se očekává List? To je asi blbost že? Všechno je to za běhu List. Teď si nějak neumím představit, o co jde :)

Na druhou stranu je treba diky tomu implementace Clojure pro JVM mnohem snazsi nez v .NET, takze je to neco za neco :)
V čem přesně je snazší?

(dík za odpovědi - u většiny z nich bude stačit třeba i jenom nasměrování na článek, vhodnou google frázi nebo tak něco :)
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 20. 09. 2012, 05:31:41
Jak přesně se tohle projevuje? Že List<X> nemůžu předat někam, kde se očekává List? To je asi blbost že? Všechno je to za běhu List. Teď si nějak neumím představit, o co jde :)
...nebo že do metoda(List<X>) bych měl mít možnost předat parametr typu List<Y> za předpokladu, že Y je podtřída X?
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Javista který umí anotace 20. 09. 2012, 08:05:31
Jak přesně se tohle projevuje? Že List<X> nemůžu předat někam, kde se očekává List? To je asi blbost že? Všechno je to za běhu List. Teď si nějak neumím představit, o co jde :)
...nebo že do metoda(List<X>) bych měl mít možnost předat parametr typu List<Y> za předpokladu, že Y je podtřída X?

To jde pokud metodu deklarujete takto: metoda(List<? extends X>)
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 20. 09. 2012, 08:33:18
To jde pokud metodu deklarujete takto: metoda(List<? extends X>)
Aha. Ale nemělo by to jít automaticky bez berliček? Není to trochu krkolomné? (silně na mě z toho vane duch C++ ;)
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Javista který umí anotace 20. 09. 2012, 09:02:31
To jde pokud metodu deklarujete takto: metoda(List<? extends X>)
Aha. Ale nemělo by to jít automaticky bez berliček? Není to trochu krkolomné? (silně na mě z toho vane duch C++ ;)

To není berlička ale nutnost. Nastudujte si rozdíl mezi List<? extends X> a List<? super X> a pochopíte.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 20. 09. 2012, 09:10:55
To není berlička ale nutnost. Nastudujte si rozdíl mezi List<? extends X> a List<? super X> a pochopíte.
Mluvím o tom, že celá tahle konstrukce se mi nelíbí. Považoval bych za normální, že Ypsilonem můžu Xko nahradit v jakémkoli kontextu bez toho, abych to někomu nějak zvlášť dával najevo.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Pavel Tisnovsky 20. 09. 2012, 09:19:44
Ovsem v bajtkodu se ta informace ve skutecnosti zachova ve forme metadat [...], coz si hlida prekladac ve chvili, kdyz se nekde jinde vola mujObjekt.test1() a mujObjekt.test2().
To je zajimava informace - o jaký přesně metadata se jedná? Jak se to správně jmenuje (abych si o tom mohl něco vygooglit)?

A dá se s těmi metadaty nějak softwarově pracovat? Když např. z nějakého zdroje dostanu obecný objekt a chci za běhu zjistit, jakého je typu, můžu nějak zjistit, jestli je to List<X> nebo List<Y>?

A jak je to s tou (obecnou) factory? Když mu předám obecný objekt, dá se vytvořit nová instance? Jde to nějak přibližně takhle?
Citace
Object neznamyObjekt = nepredvidatelnyZdrojObjektu.getNext();
Constructor[]  constructors = neznamyObjekt.getClass().getConstructors();
[...výběr bezparametrického konstruktoru...]
Object neznamyObjekt2 = constructor.newInstance();

Co me osobne vadi vice je fakt, ze generika (resp. ty typy) nejsou kovariantni, i kdyz by podle me mohly byt :/
Jak přesně se tohle projevuje? Že List<X> nemůžu předat někam, kde se očekává List? To je asi blbost že? Všechno je to za běhu List. Teď si nějak neumím představit, o co jde :)

Na druhou stranu je treba diky tomu implementace Clojure pro JVM mnohem snazsi nez v .NET, takze je to neco za neco :)
V čem přesně je snazší?

(dík za odpovědi - u většiny z nich bude stačit třeba i jenom nasměrování na článek, vhodnou google frázi nebo tak něco :)

Generiky v bajtkodu:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.4
http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.8

Neni to uplne jednoduchy cteni, zkusim se o tom nekdy rozepsat (sam to budu muset ted nastudovat do vetsi hloubky, nez je zdravo :)


Ad kovariance: je to treba ukazano zde: http://www.ibm.com/developerworks/java/library/j-jtp01255/index.html
Dovedu pochopit, proc to je takto navrzeno, ale z hlediska OOP (kde mame Integer extends Number a Float extends Number - dosadte si libovolnou jinou cast ze stromu hierarchiche) to cloveka nekdy prekvapi.

Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: kuka 20. 09. 2012, 09:31:59
Mluvím o tom, že celá tahle konstrukce se mi nelíbí. Považoval bych za normální, že Ypsilonem můžu Xko nahradit v jakémkoli kontextu bez toho, abych to někomu nějak zvlášť dával najevo.

Tedy bych si deklaroval List<Y> a predal ho metode, ktera pracuje s List<X>. Ta by do nej pridala instanci tridy Z (ktera je rovnez potomkem X). Potom bych postupne zpracoval prvky sveho List<Y> a volal na nich metody tridy Y. Co by se stalo, az bych narazil na instaci tridy Z? Kde by byla slibovana typova kontrola? Pro nazornost si dosadme treba X=Number, Y=BigDecimal, Z=Short.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 20. 09. 2012, 09:50:12
Generiky v bajtkodu:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.4
http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.8

Neni to uplne jednoduchy cteni, zkusim se o tom nekdy rozepsat (sam to budu muset ted nastudovat do vetsi hloubky, nez je zdravo :)
Uff, tak to je na mě fakt moc velkej guláš, to si raději počkám na ten článek (předem díky ;)

Ad kovariance: je to treba ukazano zde: http://www.ibm.com/developerworks/java/library/j-jtp01255/index.html
Dovedu pochopit, proc to je takto navrzeno, ale z hlediska OOP (kde mame Integer extends Number a Float extends Number - dosadte si libovolnou jinou cast ze stromu hierarchiche) to cloveka nekdy prekvapi.
Jasně, tak to jsem pochopil správně. Jo, je to docela matoucí - hlavně ta nekonzistence s Array.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Medik 20. 09. 2012, 10:01:18
Aby byla třída JavaBean, musí mít i konstruktor bez parametrů, viz. http://en.wikipedia.org/wiki/JavaBeans (http://en.wikipedia.org/wiki/JavaBeans)
 ;)

Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 20. 09. 2012, 10:14:10
Tedy bych si deklaroval List<Y> a predal ho metode, ktera pracuje s List<X>. Ta by do nej pridala instanci tridy Z (ktera je rovnez potomkem X). Potom bych postupne zpracoval prvky sveho List<Y> a volal na nich metody tridy Y. Co by se stalo, az bych narazil na instaci tridy Z? Kde by byla slibovana typova kontrola? Pro nazornost si dosadme treba X=Number, Y=BigDecimal, Z=Short.
U Array to nevadí? :)
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: kuka 20. 09. 2012, 10:30:14
U Array to nevadí? :)

Ne nevadi. BTW jak Array souvisi s generiky a jejich typovou bezpecnosti?
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Jakub Galgonek 20. 09. 2012, 10:35:25
U Array to nevadí? :)

Tohle se u polí kontroluje, viz ArrayStoreException.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Ladislav Thon 20. 09. 2012, 11:16:49
Tedy bych si deklaroval List<Y> a predal ho metode, ktera pracuje s List<X>. Ta by do nej pridala instanci tridy Z (ktera je rovnez potomkem X). Potom bych postupne zpracoval prvky sveho List<Y> a volal na nich metody tridy Y. Co by se stalo, az bych narazil na instaci tridy Z? Kde by byla slibovana typova kontrola? Pro nazornost si dosadme treba X=Number, Y=BigDecimal, Z=Short.
U Array to nevadí? :)

Čistě z pohledu typového systému jsou kovariantní pole špatně a invariantní generiky správně. Ovšem use-site variance je peklo na druhou...
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 20. 09. 2012, 11:17:14
Ne nevadi. BTW jak Array souvisi s generiky a jejich typovou bezpecnosti?
No tak, že to, co u generik vůbec nejde, to u Array jde, ale vyvolá to runtime výjimku.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 20. 09. 2012, 11:22:05
Čistě z pohledu typového systému jsou kovariantní pole špatně a invariantní generiky správně. Ovšem use-site variance je peklo na druhou...
Můžeš trochu rozvést důvody? (pokud možno tak, abych to jako ne-fulltime programátor, ne-javista pochopil :)
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Javista 20. 09. 2012, 11:35:44
Čistě z pohledu typového systému jsou kovariantní pole špatně a invariantní generiky správně. Ovšem use-site variance je peklo na druhou...
Můžeš trochu rozvést důvody? (pokud možno tak, abych to jako ne-fulltime programátor, ne-javista pochopil :)

U generik je to správně proto že kontroly provádí přímo kompilátor. U polí je to špatně protože kompilátor nekontroluje a může to tedy vést k pádům programů za běhu, což je přesně to co by silně typový jazyk neměl dovolovat. No a to že je to jednou tak a podruhé tak je prostě to peklo na druhou...
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: kuka 20. 09. 2012, 11:40:09
No tak, že to, co u generik vůbec nejde, to u Array jde, ale vyvolá to runtime výjimku.

A prave proto, ze by to vyvolalo behovou vyjimku, to u generik nejde, coz jsem se snazil vysvetlit. Tam by to vadilo, protoze generika zarucuji, ze k behove vyjimce nedojde, protoze se nesoulad typu objevi uz pri prekladu - to je ostatne hlavni prinos generik. Pole to nezarucuji a proto to u nich nevadi, kazdy proste vi/mel by vedet, ze k takove situaci muze dojit. Princip typove kontroly poli a generik je uplne jiny, coz je sice sveho druhu "souvislost", podle mne ale vzhledem k tematu generik irelevantni.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 20. 09. 2012, 11:53:24
U generik je to správně proto že kontroly provádí přímo kompilátor. U polí je to špatně protože kompilátor nekontroluje a může to tedy vést k pádům programů za běhu, což je přesně to co by silně typový jazyk neměl dovolovat. No a to že je to jednou tak a podruhé tak je prostě to peklo na druhou...
Ok, hledal jsem za tím něco složitějšího. Jestli je to správně, to nevím. Je to prostě tak :) Má to taky své nevýhody a v jiných jazycích se to afaik řeší jinak.

A prave proto, ze by to vyvolalo behovou vyjimku, to u generik nejde, coz jsem se snazil vysvetlit. Tam by to vadilo, protoze generika zarucuji, ze k behove vyjimce nedojde, protoze se nesoulad typu objevi uz pri prekladu - to je ostatne hlavni prinos generik. Pole to nezarucuji a proto to u nich nevadi, kazdy proste vi/mel by vedet, ze k takove situaci muze dojit. Princip typove kontroly poli a generik je uplne jiny, coz je sice sveho druhu "souvislost", podle mne ale vzhledem k tematu generik irelevantni.
No takže u polí to vadí taky, ale tam to "každý ví" :)
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Natix 20. 09. 2012, 12:05:17
Pokud jde o generické wildcards, tak tam se člověk hodně rychle dostane do situací, kdy se mu dělají uzly na mozku.  :P

Jen tak pro zajímavost:
- do List<? extends Number> nemůžu nic vložit, maximálně null
- z List<? super Number> nemůžu odebírat, respektive mám zaručeno pouze to, že tyto objekty budou implementovat lava.lang.Object

Naštěstí existuje docela použitelná mnemotechnická pomůcka od Joshe Blocha: PECS - Producer Extends, Consumer Super
Nicméně už jenom přijít na to, co je ten producent a konzument, je občas problém. Pak to vede na úchvatné signatury metod typu:

Kód: [Vybrat]
public static <T extends Comparable<? super T>> void sort(List<T> list)
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: kuka 20. 09. 2012, 12:11:47
A prave proto, ze by to vyvolalo behovou vyjimku, to u generik nejde, coz jsem se snazil vysvetlit. Tam by to vadilo, protoze generika zarucuji, ze k behove vyjimce nedojde, protoze se nesoulad typu objevi uz pri prekladu - to je ostatne hlavni prinos generik. Pole to nezarucuji a proto to u nich nevadi, kazdy proste vi/mel by vedet, ze k takove situaci muze dojit. Princip typove kontroly poli a generik je uplne jiny, coz je sice sveho druhu "souvislost", podle mne ale vzhledem k tematu generik irelevantni.
No takže u polí to vadí taky, ale tam to "každý ví" :)

Pouzij prosim hlavu a zamysli se nad tim, co znamena, kdyz neco zarucuje specifikace - to proste fungovat MUSI. U poli to mozna subjektivne vadi tobe, ale to je trochu jiny smysl slova "vadit". Nekompatibilita poli a generik je problem, ktery realne nastava minimalne. V 99% uloh neni zadny duvod pouzivat pole misto kolekci a nedoporucuje se to (napr. proto, ze pole jsou z principu vzdy modifikovatelna). Pole maji misto tam, kde je potreba vysoky vykon, predevsim ve vztahu k primitivnim typum.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 20. 09. 2012, 12:17:49
Pak to vede na úchvatné signatury metod typu:
Kód: [Vybrat]
public static <T extends Comparable<? super T>> void sort(List<T> list)
No dyť jsem říkal, že z toho na mě dýchá C++ ;)
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 20. 09. 2012, 12:20:30
@kuka: asi si nerozumíme. Chtěl jsem říct, že ve mně budí podezření jazyky, kde A funguje nějak a B, které je A velmi podobné, funguje úplně opačně - ale zároveň komunita tvrdí, že to, jak B funguje, je bomba.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: podlesh 20. 09. 2012, 12:21:55
V 99% uloh neni zadny duvod pouzivat pole misto kolekci a nedoporucuje se to (napr. proto, ze pole jsou z principu vzdy modifikovatelna). Pole maji misto tam, kde je potreba vysoky vykon, predevsim ve vztahu k primitivnim typum.
Pole se bohužel používají zcela běžně jako varargy...

Dále jsou běžné v různých API včetně těch základních (java.*, javax.*) a kolekce jsou koneckonců implementované nad nimi (a celé praktické používání generik je pak zajištěno tím že jsou na implementacích vypnuté pomocí @SuppressWarning, což je dost drsný hack).

Bohužel toho všeho se nedá jen tak jednoduše vyřešit bez problémů se zpětnou kompatabilitou nebo novou "paralelní" verzí jazyka. A v tom případě je lepší prostě použít zbrusu nový jazyk. Například Groovy, Scala, Clojure.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: podlesh 20. 09. 2012, 12:25:06
Pak to vede na úchvatné signatury metod typu:
Kód: [Vybrat]
public static <T extends Comparable<? super T>> void sort(List<T> list)
No dyť jsem říkal, že z toho na mě dýchá C++ ;)
To je matematika (viz http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science) (http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science))), takže to tak nějak dopadnout musí (dokonce ani přesun do jiného vesmíru nepomůže).
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: kuka 20. 09. 2012, 12:42:51
@kuka: asi si nerozumíme. Chtěl jsem říct, že ve mně budí podezření jazyky, kde A funguje nějak a B, které je A velmi podobné, funguje úplně opačně - ale zároveň komunita tvrdí, že to, jak B funguje, je bomba.

Aha, podezreni neni to, o cem bych se chtel bavit, natoz o komunite. Ja jsem chtel pouze vysvetlit, proc neni spravna tvoje uvaha, ze "pro Y potomka X bych List<Y> mel mit moznost pouzit kdekoliv, kde List<X>, aniz bych to nejak specialne daval najevo". Bud se to povedlo, nebo nepovedlo, ale vic k tomu asi neni co rict.
Název: Re:K čemu je v Javě prázdný String konstruktor?
Přispěvatel: Mirek Prýmek 20. 09. 2012, 12:52:37
Aha, podezreni neni to, o cem bych se chtel bavit, natoz o komunite.
Ok, nemám důvod to dál rozpitvávat.