Dobry den, mohl by mi nekdo vysvetlit nasledujici kus textu?
// je vyhodnejsi pouzivat rozhrani
// misto implementacni tridy
HashSet hs = new HashSet();
Jak by to melo byt spravne a take proc?
diky
No v Jave nedelam a uz si nepamatuju moc terminologii,
ale rozhrani je vlastne vicenasobne dedeni, ale
pouze od abstraktni tridy, tj. dedite od objektu,
ktery ma metody, ktere nic nedelaji a musite je
naimplementovat a to je to rozhrani. V jave se
takoveto postupy potom nazyvaji "vyhoda", ale asi
se najdou lide, kteri to dokazi popsat daleko jadrneji.
Asi v kazde trochu slusnejsi knizce o jave se o tom
bude psat (v knizkach o C++ nekdy take). Kazdopadne,
jestli prijde "pam Smalltalk", "pan Rychlost" a
pan "Java_je_enterprise", bude tu na toto tema
poucny flamewar.
Spravne by to asi melo byt:
// je vyhodnejsi pouzivat rozhrani
// misto implementacni tridy
Set hs = new HashSet();
Protoze pak je mozne snadno zmenit implementacni tridu (HashSet za nejakej MujSet) bez dopadu na typ reference hs (hs bude i nadale typu Set).
aha uz to asi chapu, cetl jsem o necem podobnem v knize od pana Eckela.
kod se zmeni jen na leve strane? treba:
Collection seznam = new ArrayList()?
diq
Ano - jeste je treba poznamenat, ze hlavni smysl (podle me:)) neni v tom ze si "usetrim" zmenu leve strany, ale v tom, ze reference seznam je typovana na rozhrani (collection) ktere rika, jakym zpusobem se odkazovany objekt umi chovat a ne jakym zpusoben je implementovan (to rika ta trida ArrayList - implementovano pomoci nejakeho pole asi) - tj. objekt na referenci seznam je kolekce implementovana pomoci ArrayList.
Pokud to bude umet odhalit i mrtvy kod, tak to je opravdu hodne uzitecne pro procisteni vetsiho projektu. Jdu to hnedka stahnout :-)
Pracuje to na urovni jednoho zdrojoveho textu (souboru), tudiz to odhali nepouzite private metody a promenne. U public veci si musi kazdy pomoct jak umi - neco muze napovedet obfuskator pokud mu spravne zadate entry points vasi aplikace.
Osobni zkusenost je, ze to vycisti importy (ackoliv nepozna, ze 'import a.b.*;' je zbytecny), ty zbytecne private veci a zbytek zavisi na tom jak vyvjari dodrzuji coding conventions behem vyvoje. Uzitecne a v kombinaci s IDE i snadne k pouziti. Doporucuju.
Tak to je skoda. Dost z toho umi i CheckStyle (take jen pro jeden soubor). Ale ten neumi poznat nepouzitou (nebo neprectenou) promennou, prip. mrtvy kod.
Chtelo by to neco co sleduje i vsechny mozne cesty programem (i skrz vice trid). Jenze to uz je asi dost komplexni a kdo tohle naprogramoval tak uz to zrejme prodava jako komercni produkt a slusne na tom vydelava ... :-)
V tomto ohledu bohuzel musim konstatovat, ze to obecne nelze udelat :-( Dokonce ani nelze obecne sestavit algoritmus, ktery by overil, zda zkoumany algoritmus neni nahodou nekonecny.
Ku zkoumani doporucuji nalistovat ucebnici na tema Turinguv stroj a podobne zalezitosti.
Ten dukaz Turingovym strojem o nemožnosti určit, zda program skončí nebo ne, je jen o tom, že se jednou programu zadá vstup tak, aby skončil a jednou tak aby neskončil a potom nelze rozhodnout.
Toto zadání je však nesmyslné. Na vstupu samozřejmě záleží a minimálně jeho gramatika by měla být součástí ověřování.
Z toho "důkazu" se potom celá léta vyvozuje, že nelze vytvořit systém, který by prověřil program a řekl je-li ok nebo ne. Přitom je možné vytvořit velmi užitečný systém, který bude prověřovat vstupní podmínky, Assert .... a mohl by pro určité známé konstrukce potvrdit správnost/nesprávnost.
Asi Vas sklamem, ale ani pri specifikovani vstupnych podmienok velmi dalej nezajdete. Presnejsie povedane, ano, existuju triedy programovych schem, pre ktore sa pri zadanych vstupnych podmienkach da urcit, ci program skutocne skonci.
V praxi vsak taketo programy nenajdete - max. algoritmus na par desiatok riadkov, ktory bol pisany specialnym sposobom, prave kvoli moznosti dokazu konecnosti alebo spravnosti.
Prip. si prectete tenhle clanek, myslim ze tam zastaveni touringova stroje apod. neresili, viz. http://www.stanford.edu/~engler/p401-xie.pdf
Tipnul bych si ze je to neco na zpusob prohledavani grafu (z daneho startovaciho bodu) a oznaceni nedostupnych uzlu. Ale je fakt, ze ten algoritmus detailne nepopisovali.
Nevim, jestli to neni uplne mimo misu, ale existuje neco takovyho i pro C++?
Neco podobneho existuje i pro C++. Viz.
http://www.stanford.edu/~engler/p401-xie.pdf
Aplikovali to na kod linuxoveho jadra.
Ten clanek mne dost inspiroval k hledani statickeho checkeru pro Javu.
Bohuzel ale autori nezverejnili zdrojove kody tech jejich nastroju, ale zminujou se o podobnych free nastrojich.
Pro C++ existuje PC-Lint, ale tusim, ze neni free.
http://www.gimpel.com/html/order.htm
Ten dovede zkontrolovat cely projekt, oproti zde zminovanemu PMD, ktery jen jeden soubor.
Myslel jsem ze optimalizace:
if (1 == 2) return false;
else return true;
na
return (1 == 2);
je soucasti kazdeho Java kompilatoru (i C++).
Stejne tak
String a = "bla"
a
String a = new String("bla");
jsou prelozeny naprosto stejne ve vyslednem byte codu.
Mylil jsem se ???
String a = "bla"
a
String b = new String("bla");
neni prelozeno stejne, ve druhem pripade se vytvari novy objekt. Zkuste si porovnat jestli
a == b, nerovnaji se. 'a' a 'b' odkazuji na ruzne objekty na heapu (i kdyz se stejnou hodnotou).
Je jasny, ze se vytvari novy objekt. Jde o to, zda kompiler z obou notaci ve vysledku udela stejny byte code, nebo ne.
V obou pripadech se IMHO nevygeneruje stejny byte kod.
V prvnim pripade: String a = "abc";
se pouzije objekt String z poolu String konstant a novy objekt se dynamicky nevytvari (jen se priradi odkaz na konstantu).
Ve druhem pripade:
String b = new String("abc");
se (zbytecne) vytvari novy objekt (kopie konstanty "abc"), zbytecne vetsi rezie za behu.
String a = new String("bla");
String b = new String("bla");
mi taky vytvoří dva různé objekty (identickým způsobem). Plyne z toho něco?
Plyne z toho to, ze je to neefektivni. Zbytecne se vytvari 2 nove String objekty, misto znovupouziti jedne jiz existujici String konstanty:
String a = "bla";
String b = "bla";
Zde v bytekodu nebude ani jedno zbytecne "new".
Obojí znamená naprosto totéž, přeloží se to vždy stejně. Oba řádky znamenají vytvoření nového objektu a zavolání konstruktoru s jedním parametrem, kterému se předá hodnota "bla".
Není to pravda - používaní literálů a konstrukce new String("asd") vede k jiným výsledkům a i v chování.
public class Pokus {
public static void main(String[] args) {
String a = "asdf";
if (a == new Hu().x) {
System.out.println("true a hotovo");
}
}
}
class Hu {
String x = "asdf";
}
Toto by v případě použití konstrukce new mělo jiný výsledek.
Zajimava vec,
jeste zajimavejsi me prijde fakt, ze nasledujici kousek taky projde:
public class Pokus {
static String b = "a" + "s" + "d" + "f";
public static void main(String[] args) {
String a = "asdf";
if (a == b) {
System.out.println("true a hotovo");
}
}
}
Zajimalo by me, jestli je toto chovani ve specifikaci, nebo se lisi v ruznych implementacich Javy.
Mate v tom celkem chaos ... se mi zda
String a = "ads";
a
String b = new String("ads");
je UPLNE to same. U obou se vytvori novy objekt String a je nainicializovan na danou hodnotu. String se ale pri porovnavani chova trochu "podivne" a neporovnava se rovnost objectu, ale rovnost obsahu.
A co vice, kdyz se podivate do byto codu, co vznikne pri
String a = "a" + "b" + "c";
tak je to celkem zbesile, na kazde string, literal, se vytvori novy StringBuffer object a k nemu se pak "appendne" dalsi a dalsi a na vysledek se udela new String(strBuffer.toString());
K rozhodnutí, zda překládá java výrazy
String a = "abcdefg"
a
String a = new String("abcdefg")
jsem si vytvořil dva programy:
public class Test1 {
public static void main (String [] args) {
String a = "abcdefg";
}
}
a
public class Test2 {
public static void main (String [] args) {
String a = new String ("abcdefg");
}
}
První má po přeložení (tj. soubor Test1.class) 275B, druhý (soubor Test2.class) má 338B. Pomocí programu javap lze převést bytecode do čitelného tvaru, metoda main v prvním programu vypadá následovně:
Method void main(java.lang.String[])
0 ldc #2 <String "abcdefg">
2 astore_1
3 return
Metoda main v druhém programu vypadá následovně:
Method void main(java.lang.String[])
0 new #2 <Class java.lang.String>
3 dup
4 ldc #3 <String "abcdefg">
6 invokespecial #4 <Method java.lang.String
(java.lang.String)>
9 astore_1
10 return
Testy jsem prováděl pod Windows XP s JDK 1.4.0
Luboš Pavlíček
P.S. Též jsem si myslel, že to přeloží stejně. Z tohoto příkladu nevyplývá, jak to přeloží jiné překladače (jikes, SDK od IBM, ...).
Byla vydána nová vývojová verze datového formátu a souvisejících nástrojů Relational pipes. Hlavní novinkou verze v0.10 je nástroj…
Zabbix slouží k monitorování aktivních síťových prvků (PC, servery, tiskárny, modemy, switche, UPS…), které jsou připojené do počítačové sítě…
Příští týden bude na MFF UK zahájena série přednášek o výhodách a zádrhelích dynamického překladu. Budete mít možnost prozkoumat virtuální…
Internet Info Root.cz (www.root.cz)
Informace nejen ze světa Linuxu. ISSN 1212-8309
Copyright © 1998 – 2019 Internet Info, s.r.o. Všechna práva vyhrazena.