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.
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.
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 ... :-)
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.
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.
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.
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, ...).