Jsou Java generics opravdu špatné?

Re:Jsou Java generics opravdu špatné?
« Odpověď #15 kdy: 11. 05. 2014, 22:34:04 »
Ma tam u instanci vytvorit prave pomoci ty moji factorky a po uzivatli tridy chtit, aby dodal tu factory (napriklad pridat ji mezi parametry metody. V tomto pripade ta factory obali kontruktor/statickou tovarnu/whatever tak, abych uvnitr ty metody moh ze Stringu ziskat objekt. V nejjednodussim pripade ta factory, co uzivatel doda bude lambda obaleni konstruktoru s argumentem typu String. Klient jiz konstruktor muz pouzit primo, nebot vi, co je F za konkretni tridu zac, nebo udelat tu prasarnu s reflexi konstruktoru, ale v tom pripade neni jiz zodpovednost na tobe, ale na nem.

AD public field: Rozhodne to nedelat. Pokud chces pri get/set pridat nejakou dalsi akci, tak automaticky rozbijes API, pres gettery/settery si muzu na pozadi delat co chci, aniz bych rozbil API (tzn klientsky kod se nemusi prizpusobovat moji zmene), navic u get je casto ta promenna virtualni (v dane tride vubec neexistuje). Rozumny IDE (napr. Eclipse) vygeneruje vsechny gettery/settery za programatora, takze argument lenosti zde postrada smysl (a zanechava spousty problemu). Zde bych i stouralum poradil jednu vec: piste kod, kterej se dobre cte a upravuje a nevymejslejte optimalizacni hovadiny, od toho tu mame prekladac


eMko

  • ****
  • 456
    • Zobrazit profil
    • E-mail
Re:Jsou Java generics opravdu špatné?
« Odpověď #16 kdy: 12. 05. 2014, 07:10:32 »
Ten ale nedokáže provést inline optimalizaci u virtuálních metod.

"Rozhodně to nedělat" bych rozhodně neříkal - spíš "dělat co nejméně, tam, kde to má smysl".

Stejně tak kód, který se dobře čte - to často znamená krátký kód.

greg

Re:Jsou Java generics opravdu špatné?
« Odpověď #17 kdy: 12. 05. 2014, 08:36:27 »
getery/settery, zabudol som, ze toto je vcelku pekne a este to o kusok znizuje potrebu pisat/nechat ide generovat veci: http://projectlombok.org. Podporuje i maven (bez neho neviem zit) a ma par peknych veci, ako napriklad moznost vygenerovat "rozumnu" toString() metodu (primarne pre "datove struktury").

Kolemjdoucí

Re:Jsou Java generics opravdu špatné?
« Odpověď #18 kdy: 12. 05. 2014, 09:47:14 »
Ten ale nedokáže provést inline optimalizaci u virtuálních metod.

V Javě jsou kompilátory dva - první kompiluje ze zdrojového kódu do bajtkódu, ten to skutečně nedokáže. Druhý (nepovinný) kompiluje z bajtkódu do strojového kódu (JIT) a tam bych si tak jistý nebyl...

Re:Jsou Java generics opravdu špatné?
« Odpověď #19 kdy: 12. 05. 2014, 11:56:11 »
AFAIK cilem JIT je optimalizace prave pro cilovou platformu


eMko

  • ****
  • 456
    • Zobrazit profil
    • E-mail
Re:Jsou Java generics opravdu špatné?
« Odpověď #20 kdy: 12. 05. 2014, 12:16:56 »
JIT virtuální metody taky AFAIK neoptimalizuje.

Kolemjdoucí

Re:Jsou Java generics opravdu špatné?
« Odpověď #21 kdy: 12. 05. 2014, 12:43:18 »
JIT virtuální metody taky AFAIK neoptimalizuje.

To je velmi silné tvrzení, protože pro JIT kompilaci neexistuje žádná specifikace takže se taková věc obecně říct nedá - dá se mluvit pouze o konkrétních implementacích. Například tady je popsaná implementace která volání vituálních metod optimalizuje: http://wasdynacache.blogspot.cz/2012/04/ibm-j9-jit-inlining-of-virtual-methods.html

noef

  • *****
  • 897
    • Zobrazit profil
    • E-mail
Re:Jsou Java generics opravdu špatné?
« Odpověď #22 kdy: 12. 05. 2014, 17:06:28 »
Jen pro zajimavost posilam priklad, jak se to da resit ve Scale (take bezi nad JVM, nekdy oznacovana jako nastupce Javy). Je to Scala script (proto asi ten neocekavany konstruktor a jmena trid). Predpokladam, ze napr. v C# to pujde resit mnohem hezceji a intuitivneji.

Kód: [Vybrat]
object Main {

  import scala.reflect._

  class Foo(ohMyName: String) {
    println(s"${getClass.getSimpleName} - $ohMyName")
  }

  class Baz(p: String) extends Foo(p)

  class SuperGeneric[F <: Foo: ClassTag] {
    val tag = classTag[F]

    def notWorkingMethod() {
      val f = tag.runtimeClass.getConstructors()(0).newInstance(Main, "win!").asInstanceOf[F]
    }
  }

  def main {
    new SuperGeneric[Foo].notWorkingMethod()
    new SuperGeneric[Baz].notWorkingMethod()
  }

}

Main.main

Kód: [Vybrat]
bash-3.1$ scala genericsNewInstace.scala
anon$1$Main$Foo - win!
anon$1$Main$Baz - win!

Natix

Re:Jsou Java generics opravdu špatné?
« Odpověď #23 kdy: 12. 05. 2014, 18:01:46 »
Jen pro zajimavost posilam priklad, jak se to da resit ve Scale (take bezi nad JVM, nekdy oznacovana jako nastupce Javy). Je to Scala script (proto asi ten neocekavany konstruktor a jmena trid). Predpokladam, ze napr. v C# to pujde resit mnohem hezceji a intuitivneji.

Kód: [Vybrat]
object Main {

  import scala.reflect._

  class Foo(ohMyName: String) {
    println(s"${getClass.getSimpleName} - $ohMyName")
  }

  class Baz(p: String) extends Foo(p)

  class SuperGeneric[F <: Foo: ClassTag] {
    val tag = classTag[F]

    def notWorkingMethod() {
      val f = tag.runtimeClass.getConstructors()(0).newInstance(Main, "win!").asInstanceOf[F]
    }
  }

  def main {
    new SuperGeneric[Foo].notWorkingMethod()
    new SuperGeneric[Baz].notWorkingMethod()
  }

}

Main.main

Kód: [Vybrat]
bash-3.1$ scala genericsNewInstace.scala
anon$1$Main$Foo - win!
anon$1$Main$Baz - win!

To je ale pořád jenom trocha syntaktického cukru nad tím, kdybys v Javě udělal:

Kód: [Vybrat]
new SuperGeneric(Foo.class).notWorkingMethod();
new SuperGeneric(Baz.class).notWorkingMethod();

noef

  • *****
  • 897
    • Zobrazit profil
    • E-mail
Re:Jsou Java generics opravdu špatné?
« Odpověď #24 kdy: 12. 05. 2014, 21:24:51 »
To je ale pořád jenom trocha syntaktického cukru nad tím, kdybys v Javě udělal:

Kód: [Vybrat]
new SuperGeneric(Foo.class).notWorkingMethod();
new SuperGeneric(Baz.class).notWorkingMethod();

Jiste, to nepopiram. Jen si myslim, ze ve Scale to pujde o trochu lepe zapsat a i udrzovat. Btw nema to byt spis new SuperGeneric<Foo>(Foo.class).notWorkingMethod(); nebo neco podobneho?

Re:Jsou Java generics opravdu špatné?
« Odpověď #25 kdy: 12. 05. 2014, 22:29:18 »
No, furt je tam ta smradlava reflexe, proste neohlidas, ze si nekdo udela vlastniho potomka Foo, kterej nebude mit konstruktor s jednim paramterem typu String, kteryho bude chtit tu pouzit. Proto bych dal jako argument metody factorku, ktera tu reflexi udela za tebe

DK

Re:Jsou Java generics opravdu špatné?
« Odpověď #26 kdy: 12. 05. 2014, 22:33:52 »
To je ale pořád jenom trocha syntaktického cukru nad tím, kdybys v Javě udělal:

Kód: [Vybrat]
new SuperGeneric(Foo.class).notWorkingMethod();
new SuperGeneric(Baz.class).notWorkingMethod();

Jiste, to nepopiram. Jen si myslim, ze ve Scale to pujde o trochu lepe zapsat a i udrzovat. Btw nema to byt spis new SuperGeneric<Foo>(Foo.class).notWorkingMethod(); nebo neco podobneho?

Nutne to neni, pokud chceme zajistit, ze vratime vazne instanci dane tridy, tak to muzeme dat, jinak neni treba parametrizovat... SuperGeneric je normalni trida, ktere predas v konstruktoru nazev tridy, ze ktere vytvorit instanci... zapis bude temer identicky jako ten ve scale (dokonce bude i o trochu vice citelnejsi), na pretypovani se pouzije class.cast(instance) misto instanceOf, dokonce i vyber toho konstruktoru bude jednodussi, pokud predem vite parametry
Kód: [Vybrat]
myclass.getConstructor(String.class).newInstance("win!");

noef

  • *****
  • 897
    • Zobrazit profil
    • E-mail
Re:Jsou Java generics opravdu špatné?
« Odpověď #27 kdy: 12. 05. 2014, 23:14:41 »
@Ziktofel: jn, ja se snazil akorat prepsat bez uprav reseni do Scaly.

@DK: ono v podstate stejne to jde zapsat i ve Scale, akorat protoze jsem experimentoval s podobou konstruktoru (magie u Scala scriptu), tak jsem tam nechal to ziskavani vsech konstruktoru misto konkretniho.

popravde, kdyz se divam na dotaz, tak si nemyslim ze odpoved s predavanim Class to splnuje. dotaz je, jak z gen. parametru udelat instanci - a to asi v Jave primo nejde.

Re:Jsou Java generics opravdu špatné?
« Odpověď #28 kdy: 13. 05. 2014, 00:27:24 »
noef: ja se snazim reflexi, pokud je to mozne vyhnot, protoze je jednak pomala a jednak vede k rade mnozstvi chyb: v tomto pripade si fakt kdokoliv muze udelat vlastniho potomka Foo bez patricneho konstruktoru a pak se bude divit, proc to pada

Natix

Re:Jsou Java generics opravdu špatné?
« Odpověď #29 kdy: 13. 05. 2014, 00:32:36 »
Taky jsem pro přístup s předáním factory do konstruktoru, reflexí zahazujete statickou typovou bezpečnost do háje a vynucováním defaultních kontruktorů, setterů a mutability se kód stává akorát náchylnějším k chybám. S Javou 8 to už jde poměrně pěkně:

Kód: [Vybrat]
class Foo {}

class Boo extends Foo {}

class SuperGeneric<F extends Foo> {

    private final Supplier<F> supplier;

    SuperGeneric(Supplier<F> supplier) {
        this.supplier = supplier;
    }
   
    void notWorkingMethod() {
        F f = supplier.get();
    }
}

A pak jde instancovat pomocí lambda výrazu:
Kód: [Vybrat]
SuperGeneric<Boo> s = new SuperGeneric<>(() -> new Boo());
Anebo pomocí reference na metodu:
Kód: [Vybrat]
SuperGeneric<Boo> s = new SuperGeneric<>(Boo::new);