Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: Karl 05. 06. 2017, 14:50:15

Název: Java - značkovací interface
Přispěvatel: Karl 05. 06. 2017, 14:50:15
Co je to značkovací interface v Javě?
Název: Re:Java - značkovací interface
Přispěvatel: MarSik 05. 06. 2017, 15:14:34
Tipoval bych že správné klíčové slovo bude Anotace. Google pak vrátí třeba tohle: https://www.tomas-dvorak.cz/posts/java-anotace/
Název: Re:Java - značkovací interface
Přispěvatel: zamek 05. 06. 2017, 15:19:38
Interface, ktery nedefinuje zadne metody, "pritomnost znacky" se pak kontroluje treba pomoci instance of. Typicky priklad je java.io.Serializable.
Název: Re:Java - značkovací interface
Přispěvatel: Sten 05. 06. 2017, 15:20:04
Rozhraní, které nemá žádnou metodu, ale označuje třídy, které něco umí nebo k něčemu slouží:
https://en.wikipedia.org/wiki/Marker_interface_pattern
Název: Re:Java - značkovací interface
Přispěvatel: Ondra Satai Nekola 05. 06. 2017, 15:22:00
Sten a Zamek maji pravdu, jen doplnim, ze je to spis relikt z doby pred prichodem @anotaci.
Název: Re:Java - značkovací interface
Přispěvatel: Wavelet 05. 06. 2017, 15:27:13
Sten a Zamek maji pravdu, jen doplnim, ze je to spis relikt z doby pred prichodem @anotaci.
Podle mne to relikt být nemusí viz *Effective Java: Item 37*.
Název: Re:Java - značkovací interface
Přispěvatel: phi 05. 06. 2017, 17:16:32
Jen poznamka - marker interface zdedi i potomci tridy, zatimco anotace je konkretni tride.
Název: Re:Java - značkovací interface
Přispěvatel: Filip Jirsák 05. 06. 2017, 19:16:44
Jen poznamka - marker interface zdedi i potomci tridy, zatimco anotace je konkretni tride.
Což je zrovna u toho Serializable špatně.

Jak píšou ostatní, používalo se to v případech, které se dnes řeší anotacemi. Ty příklady z Effective Java ukazují zase jen příklady, kdy mají současné anotace v Javě nějaká omezení a může se vyplatit hackovat to pomocí značkovacích rozhraní místo hackování anotací.
Název: Re:Java - značkovací interface
Přispěvatel: Kit 05. 06. 2017, 20:09:48
Jen poznamka - marker interface zdedi i potomci tridy, zatimco anotace je konkretni tride.
Což je zrovna u toho Serializable špatně.

Mohu vědět, proč je to špatně? Je přece obvyklé, že potomek dědí po rodiči všechno.
Název: Re:Java - značkovací interface
Přispěvatel: Sten 05. 06. 2017, 20:39:19
Mohu vědět, proč je to špatně? Je přece obvyklé, že potomek dědí po rodiči všechno.

U té serializace, potomek může přidávat členy, které nemusí být serializovatelné, ale to značkovací rozhraní už nejde odebrat.

Ale existují rozhraní, kde to dává smysl, třeba javax.net.ssl.TrustManager nebo java.rmi.Remote.
Název: Re:Java - značkovací interface
Přispěvatel: Kit 05. 06. 2017, 20:41:47
Mohu vědět, proč je to špatně? Je přece obvyklé, že potomek dědí po rodiči všechno.

U té serializace, potomek může přidávat členy, které nemusí být serializovatelné, ale to značkovací rozhraní už nejde odebrat.

Takový potomek by však nesplňoval LSP, neměl by tedy vůbec vzniknout.
Název: Re:Java - značkovací interface
Přispěvatel: Filip Jirsák 05. 06. 2017, 22:12:09
Ale existují rozhraní, kde to dává smysl, třeba javax.net.ssl.TrustManager
Podle mne teda nedává smysl celý package javax.net.ssl od první do poslední třídy, a rozhraní TrustManager v tom není výjimkou. To není značkovací rozhraní, i v JavaDocu má napsané, že je to base interface. Zřejmě podle autorů  toho rozhraní je trust manager něco, co neumí vůbec nic.

javax.net.ssl má smysl akorát jako ukázka toho, že někteří programátoři dokáží v C++ programovat v libovolném jazyce. Kdybychom na to měli jenom Xerces, mohlo by se říct, že je to náhoda nebo omyl – proto máme stejným stylem naprogramované ještě javax.net.ssl, aby bylo jasné, že to byl záměr. Problém je v tom, že zatímco Xercesu se lze celkem snadno vyhnout, bez javax.net.ssl se v Javě neobejdete, pokud chcete používat SSL/TLS.
Název: Re:Java - značkovací interface
Přispěvatel: Filip Jirsák 05. 06. 2017, 22:17:40
Takový potomek by však nesplňoval LSP, neměl by tedy vůbec vzniknout.
To platí možná v případě, pokud se programuje čistě objektově. To ale není moc častý případ, dnes se většinou programuje „s objekty“, nebo jak to nazvat. Stačí, že si třeba do objektu potomka serializovatelné výjimky uložíte neserializovatelný objekt – parametr, který výjimku způsobil – a rázem máte neserializovatelný Serializable objekt.
Název: Re:Java - značkovací interface
Přispěvatel: Sten 06. 06. 2017, 00:01:29
Takový potomek by však nesplňoval LSP, neměl by tedy vůbec vzniknout.

Tak jasně, pokud by to bylo podle teorie OOP, tak stačí značkovací rozhraní*. Jenže reálně to nejde vždycky zařídit, stačí, když potomek třeba drží spojení přes MPI, zastupuje nějaký OpenGL objekt nebo má data v JNI, a už to nejde serializovat bez obrovského (a zbytečného, když se to nepoužije) úsilí, typicky tak, že si to pamatuje všechny kroky, jak byl ten objekt vytvořen. Často se to řeší, že ta třída implementuje readObject, která vyhazuje UnsupportedOperationException. Bohužel to nejde snadno prohnat anotačním procesorem, který se může pokusit detekovat případy, kdy se takový neserializovatelný objekt pokoušíte serializovat, a tím, že je to opt-out místo opt-in, je to dost náchylné na to, že to někdo zapomene implementovat, a pak se to třeba neodhalí ani testy, protože třeba u toho OpenGL jsou identifikátory objektů inty, u dat v JNI to zase bývají longy jakožto 64bitové pointery, oboje serializátor bez problémů sežere, a pokud se to ten test nepokusí deserializovat v jiném procesu, tak to dokonce bude fungovat.

* tedy ani ta značkovací rozhraní nedávají v čistém OOP smysl, protože nepřidávají žádnou funkčnost; to, co to značkovací rozhraní využívá, by správně mělo být implementované v tom samotném rozhraní, ale to je dané limitací Javy < 8, která neuměla default metody
Název: Re:Java - značkovací interface
Přispěvatel: Kit 06. 06. 2017, 06:09:56
Takový potomek by však nesplňoval LSP, neměl by tedy vůbec vzniknout.

Tak jasně, pokud by to bylo podle teorie OOP, tak stačí značkovací rozhraní*. Jenže reálně to nejde vždycky zařídit, stačí, když potomek třeba drží spojení přes MPI, zastupuje nějaký OpenGL objekt nebo má data v JNI, a už to nejde serializovat bez obrovského (a zbytečného, když se to nepoužije) úsilí, typicky tak, že si to pamatuje všechny kroky, jak byl ten objekt vytvořen.

Otázkou je, zda v takových případech má ještě dědičnost smysl a zda není výhodnější ji nahradit kompozicí.
Název: Re:Java - značkovací interface
Přispěvatel: dustin 06. 06. 2017, 09:02:02
Otázkou je, zda v takových případech má ještě dědičnost smysl a zda není výhodnější ji nahradit kompozicí.

Je to úplně normální situace např. ve wicketu, který vyžaduje serializovatelné fieldy a objekty modelu. DTO_A implements Serializable, přidá se nová funkcionalita používající potomka DTO_B rozšířeného o nějaké položky, u kterých se zapomene na požadavek serializovatelnosti (ač je implements zděděné) a po spuštění si wicket stěžuje, že se mu serializace nepovedla, přestože z hlediska kompilátoru je vše v pořádku.

Teorie je jedna věc, ale praxe vypadá (někdy naštěstí) jinak.
Název: Re:Java - značkovací interface
Přispěvatel: Kit 06. 06. 2017, 09:32:21
Otázkou je, zda v takových případech má ještě dědičnost smysl a zda není výhodnější ji nahradit kompozicí.

Je to úplně normální situace např. ve wicketu, který vyžaduje serializovatelné fieldy a objekty modelu.

Pokud model obsahuje serializovatelné fieldy a objekty, jednoznačně to ukazuje na kompozici.

Ještě nedávno zde proběhla debata, že dědičnost je fuj a že se má vše řešit kompozicí. Samozřejmě má dědičnost svůj význam, ale tohle není případ, kdy by měla být použita.
Název: Re:Java - značkovací interface
Přispěvatel: dustin 06. 06. 2017, 09:49:07
Ale houby, je to normální potomek, protože má stejný význam, jen nese navíc další informace - je specializovanější. Jen to "navíc" musí být také serializovatelné, což se musí zajistit ručně.
Název: Re:Java - značkovací interface
Přispěvatel: Youda 06. 06. 2017, 10:04:05
Jen poznamka - marker interface zdedi i potomci tridy, zatimco anotace je konkretni tride.

Indicates that an annotation type is automatically inherited. If an Inherited meta-annotation is present on an annotation type declaration, and the user queries the annotation type on a class declaration, and the class declaration has no annotation for this type, then the class's superclass will automatically be queried for the annotation type. This process will be repeated until an annotation for this type is found, or the top of the class hierarchy (Object) is reached. If no superclass has an annotation for this type, then the query will indicate that the class in question has no such annotation. Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class. Note also that this meta-annotation only causes annotations to be inherited from superclasses; annotations on implemented interfaces have no effect.
Název: Re:Java - značkovací interface
Přispěvatel: phi 06. 06. 2017, 13:27:08
Jen poznamka - marker interface zdedi i potomci tridy, zatimco anotace je konkretni tride.

Indicates that an annotation type is automatically inherited. If an Inherited meta-annotation is present on an annotation type declaration, and the user queries the annotation type on a class declaration, and the class declaration has no annotation for this type, then the class's superclass will automatically be queried for the annotation type. This process will be repeated until an annotation for this type is found, or the top of the class hierarchy (Object) is reached. If no superclass has an annotation for this type, then the query will indicate that the class in question has no such annotation. Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class. Note also that this meta-annotation only causes annotations to be inherited from superclasses; annotations on implemented interfaces have no effect.
Plati pro anotace s meta-anotaci @Inherited, ale neni to default. (To sem pisu hlavne proto, ze to z vaseho prispevku nejde vycist, ne proto ze bych nesouhlasil. A mate pravdu, na @Inherited jsem zapomnel.)