2015-12-25 30 views
7

Sto cercando di capire il vantaggio di un linguaggio di programmazione che viene tipizzato staticamente, e attraverso questo, mi chiedo perché dobbiamo includere il tipo nella dichiarazione? Serve a qualcosa piuttosto che a rendere esplicito il tipo? Se questo è il caso, non vedo il punto. Capisco che la tipizzazione statica consenta il controllo dei tipi in fase di compilazione, ma se omettiamo la dichiarazione del tipo esplicito, non è possibile ancora Java inferire il tipo durante la compilazione?Perché la dichiarazione di tipo è importante in un linguaggio tipizzato in modo statico?

Per esempio, diciamo che abbiamo in Java:

myClass test = new myClass(); 

non è la dichiarazione di tipo inutile qui? Se non sbaglio, si tratta di un collegamento statico e Java dovrebbe sapere che test è di tipo myClass senza dichiarazione esplicita di tipo anche in fase di compilazione.

Risposta a possibili duplicati: questa non è una domanda riguardante il tipo statico rispetto a quello dinamico, ma piuttosto l'inferenza di tipo nelle lingue tipizzate staticamente, come spiegato nella risposta accettata.

+3

e se si ha 'classe B estende A' e' A a = nuova B() '? Come dovrebbe il compilatore inferire il tipo di 'a'? – gefei

+0

@femtoRgon Questa domanda riguarda l'inferenza di tipo nelle lingue tipizzate staticamente, riguardo alle lingue digitate dinamicamente. – yshavit

+0

Siamo spiacenti, * non sulle lingue digitate dinamicamente. :) – yshavit

risposta

11

sono lingue tipizzate in modo statico che consentono di omettere la dichiarazione del tipo. Questo è chiamato type inference. Gli svantaggi sono che è più difficile progettare (per i progettisti di linguaggi), più difficile da implementare (per gli scrittori di compilatori), e può essere più difficile capire quando qualcosa va storto (per i programmatori). Il problema con l'ultimo di questi è che se molti (o tutti) i tuoi tipi sono dedotti, il compilatore non può dirti molto di più di "i tipi non sono tutti coerenti" - spesso tramite un messaggio criptico.

In un caso banale come quello che citi, sì, è facile. Ma man mano che ti allontani dal caso banale, il sistema diventa rapidamente più complesso.

Java in realtà esegue un po 'di inferenza di tipo, in forme molto limitate. Per esempio, in questo frammento:

List<String> emptyStrings = Collections.emptyList(); 

... il compilatore ha dedotto che la chiamata al metodo restituisce un emptyListList<String>, e non solo un List<T> cui il tipo T non è specificato. La versione non derivata di quella linea (che è anche Java valida) è:

List<String> emptyStrings = Collections.<String> emptyList(); 
+1

Questo è esattamente quello che stavo chiedendo, grazie !! Così ora ho un'altra domanda simile: il tipo dichiarato assegna una diversa quantità di memoria in un linguaggio come Java? Come 'A a;' vs 'B b;', se 'A' ha 100 variabili di istanza e B ha 0, diciamo, farebbe qualche differenza durante la dichiarazione, o viene solo dopo l'istanziazione? Che ne dici di primitivi? – rb612

+2

@ rb612 Non fa alcuna differenza; il ricordo è determinato esclusivamente dall'oggetto, non dal riferimento ad esso. Il riferimento è solo una dimensione fissa, quindi i tre riferimenti 'String a',' Lista b' e 'ArrayList > c' occuperanno tutti esattamente lo stesso spazio (e in realtà, la JVM ha vinto so anche che sono qualcosa di diverso da "un riferimento ad un oggetto"). I primitivi non hanno affatto il polimorfismo, ma hanno dimensioni diverse (un byte è solo un byte, un corto è due byte, ecc.). – yshavit

+0

è fantastico, grazie! quindi, in sostanza, la dichiarazione esplicita di tipo in un linguaggio tipizzato in modo statico come Java serve solo per evitare l'inferenza di tipo e non ha nulla a che fare con l'allocazione della memoria? – rb612

1

È necessario. Puoi avere ereditarietà, dove i tipi sono necessari.

Ad esempio:

Building build1 = new House(); 
Building build2 = new SkyScraper(); 

è lo stesso in polimorfismo.

È quindi possibile raccogliere tutti gli Building s per l'array ad esempio. Se ci sarà uno House e uno SkyScraper non puoi farlo.

+0

Giusto, posso vederlo. Ma se volessi costruire1 solo per essere una casa, come 'House build1 = new House();', non dovresti essere in grado di rilasciare la prima House e scrivere 'build1 = new House();'? – rb612

+0

risposta modificata @ rb612 – maskacovnik

+0

Grazie.Penso che la mia domanda non sia stata formulata correttamente e abbia avuto più a che fare con l'inferenza di tipo, che è ciò che è spiegato nella risposta di @yshavit. – rb612