Comparația bibliotecii în java și c. Comparație între C Sharp și Java

Și eliberarea de memorie nu este specificată în mod explicit. Ambele includ mecanisme de sincronizare în sintaxa lor.

Atât Java cât și C# au referințe puternice și slabe la obiect. Java vă permite să înregistrați un ascultător care va primi mesaje atunci când un link este colectat de gunoi, ceea ce îmbunătățește performanța WeakHashMap, care nu există în C#. Ambele limbi permit executarea codului utilizatorului atunci când un obiect este colectat de gunoi. În C#, mecanismul pentru aceasta este o metodă specială de finalizare, exprimată prin sintaxa familiară a destructorului C++. În Java, acest lucru se realizează prin suprascrierea metodei finalize, care este declarată în clasa Object.

Tipuri de date

Ambele limbi susțin ideea (cunoscută în C# ca tipuri de valori - tipuri de valori), și ambele pentru traducerea tipurilor primitive în tipuri de obiecte asigură „împachetarea” lor automată în obiecte (boxing) și „desfășurarea” (unboxing). C# are mai multe tipuri primitive decât Java, cu tipuri de numere întregi fără semn disponibile în perechi cu toate cele semnate și un tip zecimal special pentru calcule cu virgulă mobilă de înaltă precizie. Java a abandonat majoritatea tipurilor nesemnate de dragul simplității. În special, Java nu are un tip de octet nesemnat primitiv.

Simboluri și caracteristici speciale

Java are o sintaxă statică de import specială care vă permite să utilizați nume prescurtate pentru unele sau pentru toate metodele și variabilele statice ale unei clase. C# are o sintaxă de clasă statică care restricționează o clasă doar la metode statice, dar nu există nicio modalitate de a specifica numai acele metode fără a specifica în mod explicit clasa de fiecare dată.

Cuvinte cheie speciale

Cuvânt cheie Oportunitate, exemplu de utilizare
fii gata Sintaxa C# acceptă .
afară, ref C# acceptă parametrii de ieșire a metodei, permițându-vă să returnați mai multe valori.
intrerupator În C#, instrucțiunea switch funcționează și pe șiruri.
strictfp Java folosește strictfp pentru a se asigura că rezultatele operațiunilor în virgulă mobilă sunt imuabile pe toate platformele.
verificat, nebifat În C#, expresiile sau blocurile verificate pot include verificarea depășirii aritmetice în timpul execuției.
folosind Cuvântul cheie using în C# asigură eliminarea sau închiderea cos a acestui obiect la ieșirea de la: folosind (Fișier StreamWriter = new StreamWriter("test.txt")) (fișier.Write("test"); )
mergi la C# acceptă operatorul de salt. Uneori poate fi util, deși de obicei sunt recomandate metode mai structurate de transfer al controlului (de aceea a fost abandonat în Java). O utilizare obișnuită a cuvântului cheie goto în C# este transferarea controlului către diferite etichete de caz într-o instrucțiune switch. comutați(culoare) ( case Color.Blue: Console.WriteLine("Culoarea este albastră"); break; case Color.DarkBlue: Console.WriteLine("Culoarea este închisă"); mergeți la case Color.Blue; // ... )

Gestionarea evenimentelor

Java cere programatorului să implementeze manual modelul de observator, deși oferă unele sub formă de altele anonime, ceea ce vă permite să definiți corpul clasei și să creați imediat o instanță a acestuia la un moment dat în cod. Această caracteristică este de obicei folosită pentru a crea observatori.

C# oferă suport extins la nivel de limbaj pentru programarea evenimentelor, inclusiv delegați .NET, multicasting, sintaxă specială pentru setarea evenimentelor în clase, operațiuni pentru înregistrarea și anularea înregistrării gestionatorilor de evenimente, covarianța delegaților și metode anonime cu semantică completă.

Închiderile sunt propuse pentru a fi incluse în Java SE 7. Aceste închideri, ca și delegații în C#, ar avea acces deplin la toate variabilele locale dintr-un anumit domeniu de aplicare, mai degrabă decât accesul de citire la variabilele marcate final (ca și în cazul claselor imbricate anonime).

Suprasarcină de funcționare

C# include un set mare de facilități de notare, multe dintre ele, cum ar fi supraîncărcarea operatorului și definite de utilizator, sunt familiare programatorilor C++. Are, de asemenea, o implementare explicită a metodelor de interfață, care permite unei clase să implementeze metode de interfață separat de propriile metode sau să ofere implementări diferite ale metodelor cu același nume aparținând la două interfețe diferite.

Java nu include supraîncărcarea operatorului, deoarece abuzul acestuia poate duce la un cod greu de citit și dificil de depanat. În același timp, lipsa supraîncărcării în Java îl face nepotrivit pentru unele programe matematice.

Metode

În C#, metodele nu sunt implicite și trebuie declarate explicit cu cuvântul cheie virtual pentru a face acest lucru. În Java, dimpotrivă, toate metodele publice, cu excepția celor statice, sunt virtuale. Cuvântul cheie final Java este un analog cu sealed în C# și vă permite să interziceți crearea unei metode cu aceeași semnătură în clasele derivate. Virtualitatea garantează suprapunerea dorită pentru metoda apelată, dar impune o oarecare suprasarcină de execuție asupra apelurilor, deoarece aceste apeluri de obicei nu sunt supuse unei substituții inline și necesită un apel suplimentar la . Cu toate acestea, unele implementări JVM, inclusiv cele ale lui Sun, implementează înlocuirea inline a celor mai frecvent numite metode virtuale.

C# necesită o declarație explicită a intenției de a suprascrie o metodă virtuală într-o clasă derivată. Această intenție este descrisă de cuvântul cheie override. Dacă anularea nu este intenția programatorului și pur și simplu se dorește să introducă o nouă metodă virtuală cu același nume și semnătură pentru a o umbri pe cea veche, atunci este necesar un alt cuvânt cheie, new . Dacă niciunul dintre aceste cuvinte nu este specificat, aceasta duce la o eroare de compilare. În Java, orice metodă înlocuiește întotdeauna practic o metodă de clasă de bază cu același nume și semnătură, dacă există. Acest comportament este potențial periculos dacă clasa de bază a fost creată de un alt dezvoltator, iar noua versiune introduce aceeași metodă care există deja în clasa derivată; în acest caz, metoda existentă din clasa derivată va suprascrie metoda nou introdusă în clasa de bază, ceea ce nu este intenția ambilor dezvoltatori.

Compilare condiționată

C#, spre deosebire de Java, acceptă compilarea condiționată folosind . De asemenea, are un atribut Condițional, ceea ce înseamnă că metoda specificată este apelată numai atunci când constanta de compilare dată este definită. În acest fel, puteți introduce în cod, de exemplu, verificări de aserțiune, care vor funcționa numai în versiunea de depanare atunci când este definită constanta DEBUG. În biblioteca standard .NET, aceasta este metoda Debug.Assert(). Versiunile Java 1.4 și ulterioare includ o funcție de verificare a ipotezelor de rulare în limbaj.

Spații de nume și fișiere sursă

Spațiile de nume C# amintesc mai mult de C++. Spre deosebire de Java, locația fișierului sursă nu are nimic de-a face cu spațiul său de nume. Deși, strict vorbind, locația fișierelor sursă în Java nu reflectă neapărat structura de directoare a pachetului, este comportamentul implicit.

Java necesită un nume fișier sursă corespundea exact numelui singurei clase publice definite în ea, în timp ce C# vă permite să definiți mai multe clase publice într-un singur fișier și nu impune nicio restricție asupra numelui fișierului și, de asemenea (în versiunea 2.0 și ulterioară) vă permite să divizați o clasă în două sau mai multe fișiere (cuvânt cheie parțial).

Excepții

Java acceptă verificarea prin impunerea captării și gestionării complete a tuturor excepțiilor. Toate excepțiile pe care le poate arunca o metodă trebuie să fie enumerate în declarația sa folosind cuvântul cheie throws. C# nu acceptă excepțiile verificate. Unii dezvoltatori consideră că excepțiile verificate sunt foarte utile pentru a asigura un stil de programare bun. Alții, inclusiv arhitectul șef al C#, susțin că în Java au fost într-o oarecare măsură un experiment și nu s-au justificat.

Unul dintre argumentele împotriva excepțiilor verificate este că atunci când sunt utilizate, modificarea codului intern al unei funcții poate duce la aruncarea de noi excepții, ceea ce necesită o modificare a declarației acestei funcții și a tuturor celorlalte care o numesc. În cele din urmă, pentru a menține compatibilitatea interfeței, era obișnuit să se declare pur și simplu funcțiile ca throws Exception, anulând astfel întreaga idee a excepțiilor verificate. O altă modalitate de a menține compatibilitatea interfeței în Java este să prindeți excepția nou introdusă, să o înfășurați în cea veche declarată și să o aruncați din nou. De exemplu, dacă o metodă este schimbată astfel încât să acceseze baza de date în loc de sistemul de fișiere, atunci ea însăși poate prinde o SQLException și poate arunca o nouă excepție IOException, deoarece utilizatorul metodei nu ar trebui să fie conștient de detaliile acesteia. implementare internă.

Cod de nivel scăzut

Implementări

JVM și CLR

Java este omniprezent în toate tipurile de sisteme de operareși medii. Există numeroase implementări, uneori open source.

Tehnologia ClickOnce oferă funcționalități similare cu Java Webstart, dar este disponibilă numai pentru clienții Windows. Internet Explorer pe Windows poate afișa, de asemenea, formularele .NET Windows, care oferă funcționalitate asemănătoare applet-ului, dar este limitat la un anumit browser.

Standardizare

Limbajul C# nu este definit de Microsoft, ci de comitetele de standarde și . În timp ce Sun își păstrează drepturile de autor și dreptul de veto asupra platformei Java, aceasta din urmă este în mare măsură guvernată prin Java Community Process (JCP), care permite părților interesate să fie implicate în definirea de noi versiuni și caracteristici ale specificației tehnologiei Java.

Standardele ECMA și ISO pentru C# și .NET definesc limbajul, cadrul CLI și clasele de bază (Base Class Library sau BCL). Standardele nu includ multe dintre noile biblioteci pe care Microsoft le-a implementat pe lângă cadrul standard, cum ar fi biblioteci pentru baze de date, GUI și aplicații web ( , și ). Cu toate acestea, Microsoft a fost de acord în mod oficial să nu pună în judecată proiectele comunitare pentru implementarea acestor biblioteci.

Utilizare

Comunitate

Java este construit pe o cultură mai deschisă, cu firme extrem de competitive în diferite domenii de funcționalitate. Deși acest lucru rezolvă complet problema independenței furnizorului de software, adaugă o complexitate suplimentară limbajului. Pentru a utiliza cu succes bibliotecile și componentele, trebuie să cunoașteți nu numai Java, ci și toate shell-urile și cadrele concurente și diversele „trucuri” ale implementărilor.

Popularitate și dezvoltare

Java este mai vechi decât C# și este construit pe o bază mare și activă de utilizatori, devenind în multe domenii moderne ale informaticii, în special cele în care . Java domină cursurile de programare din universitățile și colegiile americane și există mult mai multă literatură despre Java astăzi decât despre C#. Maturitatea și popularitatea Java a dus la mai multe biblioteci și API-uri în Java (multe dintre ele sunt open source) decât în ​​C#.

Spre deosebire de Java, C# este un limbaj relativ nou. Microsoft a studiat limbaje existente, cum ar fi Java și , și a schimbat unele aspecte ale limbajului pentru a se potrivi mai bine nevoilor anumitor tipuri de aplicații. În timp, avantajul temporar al Java devine mai puțin semnificativ.

O critică care poate fi auzită despre Java este că se dezvoltă lent și lipsește unele caracteristici care sunt facilitate de modele și metodologii de programare la modă. O critică la adresa limbajului C# este că dezvoltatorii săi pot fi prea dornici să se adapteze tendințelor actuale în programare în detrimentul concentrării și simplității limbajului. În mod clar, designerii Java au adoptat o atitudine mai conservatoare în adăugarea de noi caracteristici majore la sintaxa limbajului decât în ​​alte limbi moderne - poate că nu dorește să lege limbajul de tendințele care termen lung poate duce la o fundătură. Java 5.0 a depășit această tendință în multe feluri, deoarece a introdus câteva caracteristici noi majore ale limbajului: bucla foreach, împachetare automată, metode variadice, tipuri enumerate, generice și adnotări (toate acestea sunt prezente în C#).

C#, la rândul său, se dezvoltă mai rapid, limitându-se mult mai puțin în adăugarea de noi caracteristici specifice problemei. Această tendință a fost evidentă mai ales în viitoarea versiune a C# 3.0, în care, de exemplu, au apărut interogări similare. (Noile caracteristici sunt concepute pentru a păstra limbajul ca limbaj de uz general. Pentru mai multe informații despre C# 3.0, consultați

Este discutabil dacă dezvoltarea C# este într-un fel un rezultat al recunoașterii de către Microsoft că un mediu de cod gestionat condus de Java are multe avantaje într-o lume din ce în ce mai conectată în rețea, în special odată cu apariția Internetului pe alte dispozitive decât computerele personale și cu creșterea importantă securitatea rețelei. Înainte ca C# să fie creat, Microsoft a modificat Java (prin crearea ) pentru a adăuga caracteristici care funcționau doar pe sistemul de operare, rupând astfel acord de licențiere. În timp ce Microsoft se afla în a doua fază a strategiei sale de afaceri, cunoscută ca , dezvoltarea J++ a fost oprită printr-un proces intentat de Sun Privat de oportunitatea de a dezvolta o clonă Java cu caracteristicile dorite, Microsoft a creat o alternativă care se potrivea mai bine nevoilor și viziunii lor asupra viitorului.

În ciuda acestui început turbulent, devine din ce în ce mai clar că două limbi rareori concurează una cu cealaltă pe piață. Java domină sectorul mobil și are mulți adepți pe piața aplicațiilor web. C# a primit o bună acceptare pe piața desktop-urilor aplicații Windowsși este împins de Microsoft ca limba principală pentru aplicațiile Windows. Datorită , C# este, de asemenea, un jucător pe piața aplicațiilor web.

Aplicații desktop

Java este uneori acuzat de promite excesiv și de livrare insuficientă atunci când vine vorba de aplicații desktop. Deși bibliotecile sale de ferestre AWT (Abstract Windowing Toolkit) se laudă cu o mulțime de capabilități, Java a trebuit să se străduiască să se impună pe piața aplicațiilor desktop. Respectarea ei strictă la principiu<пишем один раз, используем везде>face dificilă valorificarea la maximum a capabilităților și modurilor de operare specifice fiecărui sistem desktop specific. Ca rezultat, aplicațiile desktop scrise în Java arată adesea ca<чужие>pe platforma pe care sunt executate.

Sun Microsystems, spun unii, a întârziat să promoveze Java către dezvoltatori și utilizatori într-un mod care îl face atractiv pentru aplicațiile desktop. Chiar și tehnologii precum Java Web Start, care au puțini concurenți între limbi și platforme, au fost slab promovate.

Lansarea versiunii 6.0 Java, așteptată în 2006, se reorientează pe piața desktop - cu un set extins de instrumente noi și interesante pentru o integrare mai bună și mai strânsă cu mediul desktop.

înaltă tehnologie

Java acceptat ca oficial instrument software pentru utilizare în următoarea generație a standardului DVD, prin platforma interactivă BD-J. Aceasta înseamnă că conținutul interactiv, cum ar fi meniuri, jocuri, descărcări etc. se află pe toate unitățile DVD Blu-ray va fi creat pe platforma Java.

Java vs. C#... Ce poate fi mai bun decât o veșnică ceartă? Nu, acest articol nu este dedicat unui alt punct de referință și nici măcar nu este un război sfânt, nu există nici măcar o întrebare: „cine e mai tare”.

Există un instrument pentru fiecare sarcină. Compararea C# și Ruby, de exemplu, nu are sens, deoarece scopul lor este complet diferit, la fel și natura lor. Cu toate acestea, C# și Java sunt cele mai apropiate în filozofia lor.

De foarte multe ori, colegii care scriu în Java nici măcar nu sunt conștienți de multe (!!!) lucruri pe care C# le oferă (sau, dimpotrivă, nu le oferă).

Dacă sunteți interesat să vă uitați la C# și Java fără subiectivitate, și, de asemenea, aflați structura internă a acestei sau acelea oportunitati, apoi mergeți mai departe.

▌ Puțină istorie

Limbajul C# a apărut în 2001, iar dezvoltarea sa a început în 1999. Pe atunci era foarte asemănător cu Java 1.4. Cu toate acestea, C# modern, așa cum îl știm, ar trebui să înceapă cu versiunea 2.0 (care corespunde lansării Java 5).

Există o părere că C# împrumută foarte mult din Java. Cu toate acestea, nu sunt puternic de acord cu acest lucru. În opinia mea, C# este în multe privințe C cu obiecte sau C++ cu chip uman.

Sper că articolul și argumentele din el vor confirma această afirmație.
Nu o să mai povestesc Wikipedia. Prin urmare, să trecem imediat mai departe și să trecem prin diferențele și avantajele cheie.

În primul rând, ne vom uita la capacitățile JVM și CLR (Common Language Runtime) în sine, apoi ne vom uita la zahărul sintactic al C#.

▌ Episodul I: Bytecode

Atât .NET, cât și Java folosesc bytecode. Desigur, pe lângă formatul în sine, există o diferență foarte importantă - polimorfismul.

CIL (Common Intermediate Language, cunoscut și sub numele de MSIL, cunoscut și ca IL) este un bytecode cu instrucțiuni polimorfe (generalizate).

Deci, dacă Java folosește o instrucțiune separată pentru fiecare tip de operație pe diferite tipuri (de exemplu: fadd– adăugarea a 2 flotoare, adaug– adăugarea a 2 numere întregi), apoi în CIL pentru fiecare tip de operație există o singură instrucțiune cu parametri polimorfi (de exemplu, există o singură instrucțiune – adăuga, care adaugă atât elemente flotante, cât și numere întregi). Decizia de a genera instrucțiunile x86 adecvate revine JIT.

Numărul de instrucțiuni pentru ambele platforme este aproximativ același. Comparând lista de comenzi Java și CIL bytecode, puteți vedea că 206 sunt pentru Java și 232 sunt pentru CIL, dar nu uitați că în Java multe comenzi repetă pur și simplu funcționalitatea reciprocă.

▌ Episodul III: generice (tipuri parametrizate || polimorfism parametric)

După cum știți, Java utilizează mecanismul de ștergere a tipului, adică. suportul pentru generice este oferit doar de compilator, dar nu de runtime, iar după compilare, informațiile despre tipul în sine nu vor fi disponibile.

De exemplu, codul:

Listă strList = noua ArrayList (); Listă intList = noua ArrayList (); bool areSame = strList.getClass() == intList.getClass(); System.out.println(are Same);
Se va afișa Adevărat.

Mai mult, în loc de tipul generalizat T este creată o instanță a unui obiect de tip java.lang.Object.

Listă strList = noua ArrayList (); strList.add("stringValue"); String str = strList.get(0);
Va fi convertit în:

List list = new ArrayList(); list.add("stringValue"); String x = (String) list.get(0);
Deci întreaga politică de siguranță este distrus imediat.

NET, dimpotriva, are sprijin deplin generice atât în ​​timp de compilare, cât și în timpul de execuție.

Deci, ce trebuie implementat pentru a suporta pe deplin genericii în Java? În schimb, să aruncăm o privire la ceea ce a făcut echipa de dezvoltare .NET:

  • Suport pentru generice la nivel de sistem de tip comun pentru interoperabilitate între limbi
  • Suport complet de la Reflection API
  • Adăugarea de noi clase/metode la clasele de bază (Biblioteca de clase de bază)
  • Modificări ale formatului în sine și ale tabelelor cu metadate
  • Modificări ale algoritmului de alocare a memoriei de rulare
  • Adăugarea de noi structuri de date
  • Suport pentru generice de la JIT (cod-sharing)
  • Modificări în formatul CIL (noi instrucțiuni de cod de octet)
  • Suport pentru verificarea codului CIL
Acestea. genericele sunt disponibile nu numai în timpul compilării, ci și în timpul execuției fără a pierde sau a modifica informațiile de tip. Dispare și nevoia de box/unboxing.

▌ Episodul IV: Tipuri

Java este un limbaj complet OO. Se poate argumenta cu asta. Iată de ce: tipurile primitive (integer, float etc.) nu moștenesc de la java.lang.Object. Prin urmare, genericele în Java nu acceptă tipurile primitive.

Dar într-un limbaj cu adevărat OO totul este obiect.

Aceasta nu este singura limitare. De asemenea, nu este posibil să vă creați propriile tipuri primitive.

C# vă permite să faceți acest lucru. Numele acestor structuri este struct.

De exemplu:

Structură publică Quad ( int X1; int X2; int Y1; int Y2; )
De asemenea, genericele în C# vă permit să utilizați tipuri de valori (int, float etc.)

Dacă în Java trebuie să scrieți așa:

Listă intList = noua ArrayList ();
Dar nu poți face asta:

Listă intList = noua ArrayList ();
C# permite utilizarea de tipuri primitive.

Acum ajungem la subiectul ierarhiei tipurilor în .NET.

Există 3 tipuri de tipuri în .NET: tipuri de valoare, referință și pointer.

Asa de, tipul valorii– analog de tip primitiv din Java. Cu toate acestea, este moștenit de la Sistem.Obiect, locuiește nu în grămada, ci în stivă (și acum o declinare a răspunderii: locația tipului de valoare depinde de ciclul său de viață, de exemplu, atunci când participi la o închidere, boxul are loc automat).

Tip de referință– este același cu tipurile de referință în Java.

Tip pointer– este cea mai neobișnuită proprietate a .NET. Faptul este că CLR vă permite să lucrați direct cu pointerii!

De exemplu:

Struct Point ( public int x; public int y; ) nesigur static void PointerMethod() ( Punct punct; Punct* p = p->x = 100; p->y = 200; Punct punct2; Punct* p2 = (*p2) ).x = 100 (*p2).y = 200;
Seamănă foarte mult cu codul C++, nu-i așa?

▌ Episodul V: Caracteristici C#

Mai întâi, să definim ce poate face C#:
  • Proprietăți (inclusiv automate)
  • Delegații
  • Evenimente
  • Metode anonime
  • Expresii lambda
  • Arbori de expresie
  • Cursuri anonime
  • Inferență de tip puternic
  • Supraîncărcarea operatorului
  • Indexatori
  • …mult mai multe
Proprietățiîn C# reprezintă zahărul sintactic, deoarece atunci când sunt compilate, se transformă în metode de tip ObținețiXXX, SetXXX. Cu toate acestea, informațiile despre proprietatea conceptului în sine sunt stocate în metadate, astfel încât din orice altă proprietate a limbii de suport o putem accesa doar ca obiect.ProprietateX, dar nu obiect.GetPropertyX.

De exemplu:

Clasa publică TestClass ( public int TotalSum ( get ( return Count * Price; ) ) //proprietate automată - compilatorul va genera în sine câmpurile public int Count ( get; set; ) public int Price ( get ( return 50; ) ) )
Acesta va fi convertit în:

Clasa publică TestClass ( /* *toate celelalte coduri */ private int k__BackingField; //proprietate automată - compilatorul va genera în sine câmpurile public int Count ( get ( return k__BackingField; ) a stabilit ( k__BackingField = valoare; ) ) )
Delegații sunt analogi ai indicatorilor la metode în C/C++. Cu toate acestea, sunt de tip sigur. Scopul lor principal este funcțiile de apel invers, precum și lucrul cu evenimente.

În același timp, delegații în .NET sunt facilități cu drepturi depline.

Această abordare este fundamental diferită de proiectul Da Vinci pentru Java, deoarece în acestea din urmă încearcă să extindă VM-ul în sine.

Să ne uităm la un exemplu în C#:

Clasa publică TestClass ( delegat public int BinaryOp(int arg1, int arg2); public int Add(int a, int b) ( return a + b; ) public int Multiply(int first, int second) ( return first * second; ) public void TestDelegates() (BinaryOp op = new BinaryOp(Add); int rezultat = op(1, 2); Console.WriteLine(rezult); //va scoate: 3 op = new BinaryOp(Multiply); rezultat = op( 2 , 5); Console.WriteLine (rezultat: 10)
Și, de asemenea, în C:

Int Add(int arg1, int arg2) ( return arg1 + arg2; ) void TestFP() ( int (*fpAdd)(int, int); fpAdd = //indicatorul funcției int trei = fpAdd(1, 2); / / apelați funcția printr-un pointer)
Deci ce vedem? Dacă în C putem trece un pointer către o funcție cu alte tipuri de parametri (să zicem float arg1, float arg2), atunci în C# acest lucru este imposibil. În C#, delegații sunt supuși nu numai verificării semnăturii și tipului în etapa de compilare, ci și în timpul execuției.

Evenimente necesare pentru implementarea programării bazate pe evenimente. Desigur, vă puteți descurca cu un EventDispatcher sau cu modelul Publisher/Subscriber. Cu toate acestea, suportul pentru limba maternă oferă avantaje semnificative. Una dintre ele este siguranța de tip.

De exemplu:

Clasa publică MyClass ( șir privat _valoare; delegat public void ChangingEventhandler(șir oldValue); eveniment public ChangingEventhandler Schimbare; public void OnChanging(șir oldvalue) ( ​​​​​ChangingEventhandler handler = Schimbare; dacă (handler != null) handler (veche valoare); ) public șir Valoare ( get ( return _value; ) set ( OnChanging(_value); _value = value; ) ) public void TestEvent() ( MyClass instance = new MyClass(); instance.Changing += new ChangingEventhandler(instance_Changing); instanță. Valoare = „valoare șir nouă"; //будет вызван метод instance_Changing } void instance_Changing(string oldValue) { Console.WriteLine(oldValue); } } !}
Metode anonime simplifica semnificativ viața - structura clasei rămâne curată, adică nu este nevoie să creați metode suplimentare separate în clasa în sine.

Să modificăm exemplul de mai sus cu operații binare folosind metode anonime:

Clasa publică TestClass ( delegat public int BinaryOp(int arg1, int arg2); public void TestDelegates() ( BinaryOp op = new BinaryOp(delegate(int a, int b) ( return a + b; )); int rezultat = op( 1, 2);
Nu este mai scurt și mai curat?

Să luăm în considerare acum expresii lambda.

O expresie lambda este o funcție anonimă care conține expresii și operatori și poate fi folosită și pentru a crea delegați sau un arbore de expresii.

Clasa publică TestClass ( delegat public int BinaryOp(int arg1, int arg2); public void TestDelegates() ( BinaryOp op = new BinaryOp((a, b) => a + b); int rezultat = op(1, 2); Console.WriteLine(rezultat //va scoate: 3 ) )
Cum ar arăta un exemplu cu evenimente? Foarte simplu:

Clasa publică MyClass ( /* * toate celelalte coduri */ public void TestEvent() ( MyClass instance = new MyClass(); instance.Changing += (o) => Console.WriteLine(o); instance.Value = "(! LANG: valoare șir nouă"; //будет вызван Console.WriteLine } } !}
Ei bine, am redus și mai mult codul și începe să arate ca un stil funcțional (!!!). Da, și C# este limbaj funcțional, deoarece funcțiile sunt obiecte de primă clasă.

Expresiile Lambda și, odată cu acestea, arborii de expresii au fost create cu LINQ(Interogare integrată în limbă).

Încă nu sunteți familiarizat cu LINQ? Vrei să vezi cum va arăta faimosul MapReduce pe LINQ?

Clasa statică publică MyClass ( public void MapReduceTest() ( var cuvinte = nou ("...un text merge aici..."); var wordOccurrences = cuvinte .GroupBy(w => w). Selectați(intermediar => new ( Cuvânt = intermediar.Key, Frequency = intermediar.Sum(w => 1) ) .Where(w => w.Frequency > 10) .OrderBy(w => w.Frequency ) )
Sau utilizați sintaxă asemănătoare SQL:

Public void MapReduceTest() ( șir de cuvinte = șir nou ("...un text merge aici..." ); var wordOccurrences = de la w în grup de cuvinte w de w la intermediar select new ( Cuvânt = intermediar.Key, Frequency = intermediar.Suma((șir w) => 1) ) în w unde w.Frecvență > 10 ordine de w.Frecvență selectați w )
În acest exemplu vedem atât LINQ (GroupBy().Select().Where(), etc.) cât și clase anonime -

Nou ( Cuvânt = intermediar.Cheie, Frecvență = intermediar.Suma(w => 1) )
Hmm... ce se mai folosește aici? Răspunsul este simplu - un sistem de inferență de tip puternic.

Cuvântul cheie aici joacă un rol major var. C++11 are un design similar auto.

Deci, fără inferență de tip, ar trebui să scriem astfel:

Public void MapReduceTest() ( șir de cuvinte = șir nou ("...un text merge aici..." ); var wordOccurrences = Enumerable.OrderBy(Enumerable.Where(Enumerable.Select(Enumerable.GroupBy) (cuvinte, delegat (șir w) ( return w; )), delegat (IGrouping intermediar) ( return new ( Cuvânt = intermediar.Key, Frequency = Enumerable.Sum (intermediar, (Func ) (w => 1)) ); )), delegat (<>f__AnonymousType0 w) ( returnează w.Frecvență > 10; )), delegat (<>f__AnonymousType0 w) ( returnează w.Frecvența; )); )
[Aceasta metoda compilatorul ne-a generat]

Pentru a descrie toate celelalte caracteristici ale C#, setările compilatorului, etc. Este necesar să dedică mai mult de un articol.

Între timp, C# 5 – care este deja disponibil și va fi lansat oficial în curând, adaugă programare asincronă, care a apărut și în C++11!

▌ Concluzie

C# și Java sunt limbaje puternice, precum și platforme puternice (.NET și Java). După cum am scris deja la începutul articolului, există un instrument pentru fiecare sarcină.

C# nu este o continuare sau o copie a Java. Chiar și atunci când a fost dezvoltat la Microsoft, numele său de cod era COOL (C-like Object Oriented Language). De câte ori a fost citată analogia C/C++ în acest articol? Cantitate suficientă.

Sper că articolul meu a ajutat la rezolvarea (cel puțin puțin) a problemei diferențelor dintre limbi și platforme.

Vă mulțumim pentru atenție!

Sintaxă

Ambele limbaje folosesc limbajul de programare C ca bază sintactică, în special, au moștenit de la acesta fără modificări:

  • marcarea începutului/sfârșitului unui bloc de cod cu acolade;
  • notația, asociativitatea și precedența majorității operațiilor încorporate (alocare, aritmetică, logică, operații de creștere/decrementare, operator ternar condiționat " ?: »);
  • sintaxă pentru descrierea și utilizarea variabilelor și funcțiilor (ordinea „nume tip”, utilizarea modificatorilor, paranteze obligatorii pentru funcții, descrierea parametrilor formali);
  • sintaxa tuturor construcțiilor principale: operator condițional, bucle, operator de selecție multiplă;
  • lipsa procedurilor (sunt înlocuite cu funcții de tip gol);
  • nume ale tipurilor elementare încorporate (cu excepția boolului, în Java acest tip se numește boolean);
  • folosind punct și virgulă
  • ... și multe caracteristici mai mici.

Toate acestea duc la faptul că programele în Java și C# la prima vedere arată extrem de asemănătoare cu programele C. Ambele limbi au făcut extensii și completări similare la C (sau C++), în special, alfabetul a fost extins și a fost introdusă propria sintaxă care acceptă pachete, importul de descrieri și definirea unităților de compilare.

Există, de asemenea, o mulțime de diferențe sintactice.

Sintaxă Java C#
Importarea numelor statice
(import static)
vă permite să importați separat unele sau toate metodele și variabilele statice ale unei clase și să folosiți numele lor fără calificare în modulul de import Numai ansamblul este importat și de fiecare dată când utilizați nume statice importate trebuie să specificați clasa
Constante într-o declarație switch trebuie să fie fie un număr întreg, fie un tip de enumerare (în 1.7, literalele șir au fost adăugate la lista de tipuri) puteți folosi șiruri de text
du-te la operator au abandonat în mod intenționat utilizarea goto, cu toate acestea, există un mecanism care vă permite să ieșiți în bucla exterioară dintr-una imbricată prin marcarea acesteia cu o etichetă și folosind operatorii break and continue împreună cu eticheta (continuare<метка>;) goto a supraviețuit, utilizarea sa obișnuită este trecerea controlului către diferite etichete de caz într-o instrucțiune switch și ieșirea dintr-o buclă imbricată
constante Nu există constante ca atare, se folosesc variabile de clasă statică cu modificatorul final - efectul utilizării lor este exact același conceptul separat al unei constante tastate numite și cuvântul cheie const
Precizie în virgulă flotantă Java include o construcție strictfp care garantează aceleași rezultate în virgulă mobilă pe toate platformele. C# se bazează pe implementare, nu există nicio garanție pentru exact aceleași rezultate de calcul.
Dezactivarea controalelor În Java, toate verificările dinamice sunt activate/dezactivate numai la nivel de pachet C# conține constructe verificate și nebifate care vă permit să activați sau să dezactivați la nivel local verificarea dinamică a depășirii aritmetice.

În general, sintaxa C# este ceva mai extinsă și mai bogată decât Java în special, conține caracteristici precum capacitatea de a împărți descrierea unei clase în mai multe module, descrierea proprietăților și capacitatea de a controla virtualitatea; metode.

Mecanism de lucru cu date dinamice și colectarea gunoiului

Ambele limbaje implementează același model de lucru cu date dinamice: obiectele sunt create dinamic folosind noul construct, runtime monitorizează prezența referințelor la ele, iar colectorul de gunoi șterge periodic memoria obiectelor care nu au referințe. Pentru a optimiza colectarea gunoiului, specificațiile limbajelor și mediilor de rulare nu conțin restricții privind durata de viață a unui obiect după ce ultima referire la acesta este ștearsă - colectorul funcționează independent de execuția programului, astfel încât distrugerea efectivă a obiectul poate apărea în orice moment după ce ultima referință este ștearsă până când programul se termină. În realitate, colectorii de gunoi optimizează execuția pentru a asigura un consum acceptabil de memorie, reducând în același timp încetinirea programului.

C# (mai precis, common language runtime) vă permite să suprimați execuția finalizatorului pe un obiect dat folosind metoda GC.SuppressFinalize(obj) (de exemplu, o conexiune SQL pe un flux de fișiere). Acest lucru poate fi util deoarece finalizarea este considerată o operațiune relativ costisitoare în colectarea gunoiului, iar un obiect cu un finalizator va trăi mai mult.

Instrumente pentru obiecte

Tipuri de enumerare

În Java, strict vorbind, doar tablourile unidimensionale pot fi declarate. O matrice multidimensională în Java este o matrice de matrice. C# are atât matrice multidimensionale adevărate, cât și matrice de matrice, care sunt denumite în mod obișnuit „jagged” în C#. Matricele multidimensionale sunt întotdeauna „dreptunghiulare” (vorbind în terminologia bidimensională), în timp ce matricele de matrice pot stoca șiruri lungimi diferite(din nou într-un caz bidimensional, similar într-un caz multidimensional). Matricele multidimensionale accelerează accesul la memorie (pentru care pointerul este dereferențiat o singură dată), în timp ce matricele zimțate sunt mai lente, dar economisesc memorie atunci când nu toate rândurile sunt pline. Matricele multidimensionale necesită un singur apel către noul operator pentru a le crea, în timp ce tablourile eșalonate necesită alocarea explicită a memoriei într-o buclă pentru fiecare rând.

Tipuri parametrizate (generice).

În ambele limbi, tipurile pot fi parametrizate, ceea ce acceptă paradigma de programare generică. Sintactic, definiția tipurilor este destul de apropiată - în ambele limbi este moștenită din șabloanele C++, deși cu unele modificări.

Tipurile generice în Java sunt pur o construcție de limbaj și sunt implementate numai în compilator. Compilatorul înlocuiește toate tipurile generice cu limitele lor superioare și inserează modele de tip adecvate oriunde este utilizat un tip parametrizat. Rezultatul este bytecode care nu conține referințe la tipuri generice și parametrii acestora. Această tehnică de implementare a tipurilor generice se numește ștergerea tipului(tergere tip). Aceasta înseamnă că informațiile despre tipurile generice originale nu sunt disponibile în timpul execuției și impune unele limitări, cum ar fi incapacitatea de a crea instanțe noi de matrice din argumente de tip generic. Runtime-ul Java nu este familiarizat cu sistemul de tip generic, așa că noile implementări JVM au necesitat doar actualizări minime pentru a gestiona noul format de clasă.

C# a mers pe o altă cale. Suportul pentru generalitate a fost integrat în runtime virtual în sine, apărând pentru prima dată în .NET 2.0. Limbajul aici a devenit doar o interfață externă pentru accesarea acestor capabilități ale mediului. Ca și în Java, compilatorul efectuează verificarea tipului static, dar pe lângă aceasta, JIT efectuează verificarea corectitudinii timpului de încărcare. Informațiile despre tipurile generice sunt prezente pe deplin în timpul execuției și permit suport complet pentru reflectarea tipurilor generice și crearea de noi implementări ale acestora.

Abordarea Java necesită verificări suplimentare în timpul execuției, nu garantează că clientul de cod va respecta conformitatea tipului și nu oferă reflectare pentru tipurile generice. Java nu permite ca tipurile generice să fie specializate în tipurile primitive (acest lucru se poate face numai prin împachetarea tipurilor primitive în clase), în timp ce C# oferă generice atât pentru tipurile de referință, cât și pentru cele de valoare, inclusiv primitive. În schimb, Java sugerează utilizarea tipurilor primitive încapsulate ca parametri (de exemplu, List în loc de Listă ), dar acest lucru vine cu prețul alocării suplimentare de memorie dinamică. Atât în ​​Java, cât și în C#, specializările de tip generic pe diferite tipuri de referință produc același cod, dar pentru C#, runtime-ul generează în mod dinamic cod optimizat atunci când se specializează pe tipuri de valori (de exemplu, Listă). ), care le permite să fie depozitate și scoase din containere fără operațiuni de încărcare și derulare.

Gestionarea evenimentelor

Java cere programatorului să implementeze manual modelul de observator, deși oferă un oarecare zahăr sintactic sub formă de clase anonime imbricate, ceea ce vă permite să definiți corpul unei clase și să îl instanțiați imediat într-un singur punct al codului.

C# oferă suport extins la nivel de limbaj pentru programarea evenimentelor, inclusiv delegați .NET, multicasting, sintaxă specială pentru setarea evenimentelor în clase, operațiuni pentru înregistrarea și anularea înregistrării gestionatorilor de evenimente, covarianța delegaților și metode anonime cu semantică de închidere completă.

Închiderile sunt propuse pentru a fi incluse în Java SE 8. Aceste închideri, ca și delegații în C#, ar avea acces deplin la toate variabilele locale dintr-un anumit domeniu de aplicare, mai degrabă decât accesul de citire la variabilele marcate final (ca și în cazul claselor imbricate anonime).

Suprasarcină de funcționare

Proprietăți

C# acceptă conceptul de „proprietăți” - pseudo-câmpuri ale unei clase care sunt accesate într-un mod complet controlat prin crearea de metode pentru a prelua și scrie valoarea câmpului. Declarațiile de proprietate sunt făcute folosind constructele get și set.

C# include, de asemenea, ceva numit indexatori, care poate fi considerat un caz special de supraîncărcare a operatorului (similar cu supraîncărcarea operatorului în C++), sau proprietăți parametrizate. Un indexator este o proprietate numită astfel, care poate avea unul sau mai mulți parametri (indici), iar indecșii pot fi de orice tip. Acest lucru vă permite să creați clase ale căror instanțe se comportă ca matrice:

Lista mea[ 4 ] = 5 ; nume șir = xmlNode. Atribute[„nume”]; comenzi = customerMap[ theCustomer] ;

Utilizarea proprietăților este respinsă de unii programatori de renume. În special, Jeffrey Richter scrie:

„Personal, nu-mi plac proprietățile și m-aș bucura dacă suportul pentru ele ar fi eliminat de la Microsoft. Cadru netși limbaje de programare aferente. Motivul este că proprietățile arată ca câmpuri, dar sunt de fapt metode.”

Conform stilului obișnuit de denumire C#, numele proprietăților se disting vizual de numele câmpurilor prin faptul că încep cu o literă mare.

Compilare condiționată

C#, spre deosebire de Java, acceptă compilarea condiționată folosind directive de preprocesor. De asemenea, are un atribut Condițional, ceea ce înseamnă că metoda specificată este apelată numai atunci când constanta de compilare dată este definită. În acest fel, puteți introduce în cod, de exemplu, verificări de aserțiune, care vor funcționa numai în versiunea de depanare atunci când este definită constanta DEBUG. În biblioteca standard .NET, aceasta este metoda Debug.Assert().

Versiunile Java 1.4 și ulterioare includ o funcție de verificare a ipotezelor de rulare în limbaj. În plus, dacă constructele cu condiții constante pot fi extinse în timpul compilării. Există implementări de la terțe părți ale preprocesoarelor pentru Java, acestea fiind utilizate în principal atunci când se dezvoltă aplicații pentru dispozitive mobile.

Spații de nume, ansambluri, pachete

C# folosește spații de nume(spațiul de nume), care amintește de mecanismul C++ cu același nume. Fiecare clasă aparține unui spațiu de nume acele clase pentru care spațiul de nume nu este specificat explicit aparțin implicit spațiului de nume nenumit. Spațiile de nume pot fi imbricate unul în celălalt.

Java are pachete, oarecum similar cu spațiile de nume C#. Pachetele pot fi imbricate, fiecare clasă descrisă aparține unui anumit pachet în absența unei indicații explicite a pachetului, clasa aparține unui pachet global fără nume.

În ambele limbi, pentru a accesa un obiect declarat într-un alt spațiu de nume sau pachet, trebuie să declarați pachetul necesar (spațiul de nume) din program ca fiind utilizat. Un obiect este accesat printr-un nume calificat, numele pachetului (spațiul de nume) este folosit ca calificator. Dacă este necesar accesul la un obiect fără calificare, modulul programului trebuie să conțină o directivă de dereferire: utilizarea în C# și importul în Java.

În C#, spațiile de nume nu sunt asociate în niciun fel cu modulele compilate (ansambluri sau asamblare în terminologia Microsoft). Mai multe ansambluri pot conține același spațiu de nume, iar un ansamblu poate declara mai multe spații de nume, nu neapărat imbricate. Modificatorii domeniului C# nu au nimic de-a face cu spațiile de nume. În Java, clasele declarate implicit în același pachet formează un singur modul compilat. Modificatorul implicit al domeniului de aplicare (fără specificații explicite) limitează domeniul de aplicare al câmpurilor și metodelor unei clase la limitele pachetului.

În Java, structura fișierelor și directoarelor codului sursă al unui pachet este implicit asociată cu structura pachetului - un pachet corespunde unui director, subpachetele incluse în acesta - subdirectoarele acestui director, fișierele sursă sunt situate în directoare corespunzătoare pachetului sau subpachetului în care sunt incluse. Astfel, arborele sursă urmează structura pachetului. În C#, locația unui fișier sursă nu are nimic de-a face cu spațiul său de nume.

Locația textului sursă în fișiere

În C#, clasele pot fi localizate în fișiere în orice mod. Numele fișierului de cod sursă nu are nimic de-a face cu numele claselor definite în acesta. Este permisă plasarea mai multor clase publice într-un singur fișier. Începând cu versiunea 2.0, C# vă permite de asemenea să împărțiți o clasă în două sau mai multe fișiere (cuvântul cheie parțial). Ultima caracteristică este utilizată în mod activ mijloace vizuale construcția interfeței: partea clasei care conține câmpurile și metodele controlate de constructorul de interfață este alocată în dosar separat, pentru a nu aglomera fișierul editat direct de programator cu codul generat automat.

În Java, fiecare fișier poate conține o singură clasă publică, iar Java necesită ca numele fișierului să fie același cu numele acelei clase, eliminând confuzia între numele fișierului și al clasei. Mai mult, conform convenției de codare recomandate de Sun, dimensiunea unui fișier cu cod sursă nu trebuie să depășească 2000 de linii de cod, deoarece un fișier mai mare este mai dificil de analizat. Dimensiunea mare a fișierului este, de asemenea, considerată un semn al deciziilor slabe de proiectare.

Excepții

Ambele limbi suportă un mecanism de gestionare a excepțiilor, proiectat sintactic exact în același mod: limbajul are un operator de generare a excepțiilor aruncași bloc de tratare a excepțiilor încercați()catch()()în final(), care asigură interceptarea excepțiilor care apar în cadrul unui bloc, prelucrarea acestora, precum și executarea garantată a acțiunilor finale.

Java acceptă excepții verificate: programatorul trebuie să specifice în mod explicit pentru fiecare metodă tipurile de excepții pe care metoda le poate arunca, aceste tipuri sunt listate în declarația metodei după cuvântul cheie throws. Dacă o metodă utilizează metode care aruncă excepții verificate, trebuie fie să prindă în mod explicit toate aceste excepții, fie să le conțină în propria declarație. Astfel, codul conține în mod explicit o listă de excepții care pot fi aruncate de fiecare metodă. Ierarhia tipurilor de excepție conține și două tipuri (RuntimeException și Error), ai căror descendenți nu sunt verificați și nu trebuie descriși. Ele sunt rezervate pentru excepțiile de rulare care pot apărea oriunde sau nu pot fi gestionate în mod normal de programator (cum ar fi erorile de rulare) și nu ar trebui să fie specificate într-o declarație throws.

C# nu acceptă excepțiile verificate. Absența lor este o alegere deliberată a dezvoltatorilor. Anders Hejlsberg, arhitectul șef al C#, crede că în Java au fost într-o oarecare măsură un experiment și nu s-au justificat.

Programare în paralel

În general, mecanismele de programare paralelă în C# sunt similare cu cele oferite de Java, diferența constă în detaliile implementării. În ambele cazuri, există o clasă de bibliotecă Thread care implementează conceptul de „thread”. Java oferă două moduri de a crea propriile fire de execuție: fie prin extinderea clasei Thread, fie prin implementarea interfeței Runnable. În ambele cazuri, programatorul trebuie să definească o metodă run() moștenită (inclusă în interfață) care conține corpul firului de execuție - codul care va fi executat în acesta. C# folosește în schimb mecanismul delegat: pentru a crea un fir de execuție, este creată o instanță a clasei standard Thread, căreia i se trece un delegat care conține o metodă - corpul firului de execuție - ca parametru de constructor.

Ambele limbi au capacitatea de a crea un bloc de cod executat sincron; în Java acest lucru se face folosind operatorul synchronized(), în C# - cu operatorul lock(). Java vă permite, de asemenea, să declarați metode sincrone folosind modificatorul sincronizat din antetul declarației metodei. Astfel de metode, atunci când sunt executate, își blochează obiectul proprietar (astfel, dintre metodele sincronizate ale clasei, pentru aceeași instanță, doar una poate fi executată la un moment dat, restul va aștepta). O caracteristică similară în .NET este furnizată de atributul de implementare a metodei MethodImplAttribute MethodImplOptions.Synchronized, dar spre deosebire de Java, această caracteristică nu face parte oficial din limbajul C#.

Ambele limbi oferă, de asemenea, facilități de sincronizare identice bazate pe trimiterea și așteptarea unui semnal de la un fir la celălalt(e). În Java acestea sunt metodele notify(), notifyAll() și wait(), în C# acestea sunt metodele Pulse(), PulseAll(), Wait() (cele trei metode sunt similare funcțional în perechi). Singura diferență este că în Java aceste metode (și, în consecință, funcționalitatea monitorului) sunt implementate în clasa Object, deci nu sunt necesare biblioteci suplimentare pentru sincronizare, iar în C# aceste metode sunt implementate ca metode statice într-o clasă de bibliotecă separată Monitor . În C# bibliotecă standard Conține, de asemenea, câteva primitive de sincronizare suplimentare pentru execuția paralelă a firelor de execuție: mutexuri, semafore, cronometre de sincronizare. Începând cu versiunea 1.5, JDK SE a inclus pachetele java.util.concurrent, java.util.concurrent.atomic și java.util.concurrent.locks care conțin un set cuprinzător de instrumente pentru implementarea calculului paralel.

Cod de nivel scăzut

Până în prezent, nicio componentă a mediului Java nu este standardizată de Ecma, ISO, ANSI sau de orice altă organizație de standardizare terță parte. În timp ce Sun Microsystems își păstrează drepturi legale exclusive și nerestricționate de a modifica și licenția mărcile sale comerciale Java, Sun participă în mod voluntar la un proces numit Java Community Process (JCP), care permite părților interesate să propună modificări ale oricărei tehnologii Sun Java (limbaj, set de instrumente) , API) prin consultări și grupuri de experți. Conform regulilor JCP, orice propunere de modificare a JDK, Java Runtime sau specificație limbajul Java poate fi respins unilateral de Sun, deoarece necesită un vot „da” din partea Sun pentru a fi aprobat. JCP solicită o taxă de membru de la membrii comerciali, în timp ce organizațiile non-profit și persoanele fizice pot participa gratuit.

Licență

În timp ce „Java” este o marcă comercială Sun și numai Sun poate licenția numele „Java”, există numeroase proiecte gratuite care sunt parțial compatibile cu Sun Java. De exemplu, GNU Classpath și GNU Compiler for Java (GCJ) oferă o bibliotecă de clase și un compilator gratuit care sunt parțial compatibile cu versiunea curentă a Sun Java. La sfârșitul anului 2006, Sun a anunțat că tot codul sursă Java, cu excepția codului proprietar asupra căruia nu își păstrează drepturile, va fi lansat ca software gratuit sub o licență GPL modificată până în martie 2007. Sun își distribuie în prezent HotSpot-ul Mașină virtualăși un compilator Java cu licență GPL, dar în prezent nu există o licență gratuită pentru runtime Java standard. Deoarece Sun își va păstra dreptul de proprietate asupra codului sursă Java, eliberarea acestuia sub GPL nu va împiedica Sun să distribuie proprietăți sau nedeschise. versiuni Java, sau licențiați-l altora.

C#, runtime-ul CLI și majoritatea bibliotecii de clase asociate sunt standardizate și pot fi implementate liber fără licență. Au fost deja implementate mai multe sisteme C# gratuite, inclusiv Mono și DotGNU. Proiectul Mono implementează, de asemenea, multe biblioteci Microsoft non-standard, învățând din materiale Microsoft, similare cu GNU Classpath și Java. Proiectul Mono își propune să evite încălcarea oricăror brevete sau drepturi de autor, iar proiectul poate fi distribuit și utilizat în mod liber sub licența GPL. Microsoft distribuie în prezent o versiune - a runtime-ului său .NET pentru uz necomercial.

Utilizare

Comunitate

Java este construit pe o cultură mai deschisă, cu firme extrem de competitive în diferite domenii de funcționalitate. Cele mai multe biblioteci suplimentare sunt disponibile sub licențe gratuite și open source. Sun încurajează, de asemenea, practica descrierii unor funcționalități ca o specificație (a se vedea procesul JCP), lăsând implementarea dezvoltatori terți(eventual oferind o implementare de referință). Astfel, se rezolvă problema independenței față de producătorul de software.

În ciuda existenței Mono, C# leagă strâns dezvoltatorii de platforma Microsoft (inclusiv sistemul de operare solutii de birou). Astfel, utilizatorul de software scris în .NET de multe ori nu are de ales în utilizarea diferitelor componente ale sistemului. Acest lucru duce la așa-numita blocare a vânzătorului, în care producătorul de software terță parte poate dicta cumpărătorului aproape orice condiții pentru susținerea proiectului implementat. În timp ce utilizatorul unei aplicații Java, de regulă, poate alege furnizorul de software suplimentar (cum ar fi o bază de date, sistem de operare, server de aplicații etc.).

Popularitate și dezvoltare

Java este mai vechi decât C# și este construit pe o bază mare și activă de utilizatori, devenind lingua francaîn multe domenii moderne ale informaticii, în special cele care implică rețele. Java domină cursurile de programare din universitățile și colegiile americane, iar acum există mult mai multă literatură despre Java decât despre C#. Maturitatea și popularitatea Java a dus la mai multe biblioteci și API-uri în Java (multe dintre ele sunt open source) decât în ​​C#.

Spre deosebire de Java, C# este un limbaj relativ nou. Microsoft a studiat limbaje existente, cum ar fi Java, Delphi și Visual Basic, și a schimbat unele aspecte ale limbajului pentru a se potrivi mai bine nevoilor anumitor tipuri de aplicații.

O critică care poate fi auzită despre Java este că se dezvoltă lent și lipsește unele dintre caracteristicile care fac modelele și metodologiile de programare la modă mai ușoare. O critică la adresa limbajului C# este că dezvoltatorii săi pot fi prea dornici să se adapteze la tendințele actuale de programare în detrimentul concentrării și simplității limbajului. În mod clar, designerii Java au adoptat o abordare mai conservatoare pentru a adăuga noi caracteristici majore la sintaxa limbajului decât alte limbi moderne – poate că nu sunt dispuși să angajeze limbajul în tendințele care ar putea duce la fundături pe termen lung. Java 5.0 a depășit această tendință în multe feluri, deoarece a introdus câteva caracteristici noi majore ale limbajului: bucla foreach, împachetare automată, metode variadice, tipuri enumerate, generice și adnotări (toate acestea sunt prezente în C#).

C#, la rândul său, se dezvoltă mai rapid, limitându-se mult mai puțin în adăugarea de noi caracteristici specifice problemei. Această tendință a fost evidentă mai ales în versiunea C# 3.0, în care, de exemplu, au apărut interogări de tip SQL. (Noile funcții sunt create astfel încât limbajul să rămână un limbaj de uz general. Pentru mai multe informații despre C# 3.0, consultați articolul despre C#.) Au fost luate în considerare completări la Java orientate către probleme, dar macar până în prezent, au fost respinse.

Piaţă

De la începuturile sale, C# a fost constant comparat cu Java. Nu se poate nega că C# și CLR-ul său gestionat datorează foarte mult Java și JRE (Java Runtime Environment).

Este discutabil dacă dezvoltarea C# este într-un fel un rezultat al recunoașterii de către Microsoft că un mediu de cod gestionat, cu Java lider, are multe avantaje într-o lume din ce în ce mai conectată în rețea, în special odată cu apariția Internetului pe alte dispozitive decât cele personale. calculatoare și importanța crescândă a securității rețelei. Înainte de crearea C#, Microsoft a modificat Java (creând J++) pentru a adăuga caracteristici care rulau numai pe Windows, încălcând astfel acordul de licență Sun Microsystems. În timp ce Microsoft se afla în a doua fază a strategiei sale de afaceri, cunoscută sub numele de „Embrace, Extend, and Extinguish”, dezvoltarea J++ a fost oprită de un proces intentat de Sun. Incapabil să dezvolte o clonă Java cu caracteristicile dorite, Microsoft a creat o alternativă care se potrivea mai bine nevoilor și viziunii lor pentru viitor.

În ciuda acestui început turbulent, devine din ce în ce mai clar că două limbi rareori concurează una cu cealaltă pe piață. Java domină sectorul mobil și are mulți adepți pe piața aplicațiilor web. C# a câștigat o bună acceptare pe piața aplicațiilor desktop Windows și datorită ASP.NET, C# este, de asemenea, un jucător pe piața aplicațiilor web.

Aplicații desktop

Ambele limbi au un set de biblioteci care oferă capabilități de interfață cu utilizatorul pentru aplicațiile desktop. În cazul Java, acestea sunt bibliotecile multi-platformă Swing și SWT, precum și o serie de altele mai puțin obișnuite. În principiu, oricare dintre ele vă permite să creați aplicații desktop multiplatforme în Java.

Pentru C# pe platforma Windows, biblioteca principală care implementează interfața grafică cu utilizatorul în aplicațiile desktop este Windows.Forms, deținută de Microsoft și implementată doar pentru Windows, iar pentru alte platforme - gtk#, implementată ca parte a proiectului Mono. Încercările de a implementa liber Windows.Formulare au fost și se fac (de exemplu, în proiectul DotGNU), cu toate acestea, din cauza naturii închise a originalului, ele suferă inevitabil de a fi secundare și incomplete, pot concura cu greu cu implementarea din Microsoft și, prin urmare, poate fi utilizat numai pentru portarea întârziată a aplicațiilor Windows pe alte platforme. Dezvoltarile care sunt bazate nativ pe Windows sunt de obicei construite pe Windows.Forms, iar portarea lor pe o altă platformă devine dificilă. Dezvoltarea C# în Mono folosind gtk# este portabilă, dar există mult mai puține dintre ele.

Datorită naturii limbajului, utilizarea manuală a bibliotecilor grafice Java este ceva mai dificilă. Arhitectura bibliotecilor de grafică Java este mai greu de înțeles pentru un dezvoltator începător, dar, în același timp, îl obligă să se dezvolte profesional. C#, datorită prezenței instrumentelor de programare a evenimentelor încorporate, ascunde detaliile procesării evenimentelor și alte câteva aspecte de la dezvoltator, facilitând dezvoltarea interfeței. Platforma .NET a folosit inițial pe scară largă constructorii de interfețe vizuale. Toate acestea fac posibilă dezvoltarea rapidă a unei interfețe pentru aplicații desktop cu calificări scăzute de programator.

În ultimii ani, Sun Microsystems s-a concentrat pe introducerea Java și mai pe scară largă pe piața aplicațiilor desktop. În versiunea platformei JRE 6 (2006), se pune accent pe îmbunătățirea interacțiunii cu mediu grafic utilizator. Cea mai recentă versiune a JVM-ului Sun (actualizarea JDK 6 10) include multe îmbunătățiri ale interfeței cu utilizatorul. În special, forme transparente și ferestre nedreptunghiulare. Versiunile recente ale IDE-urilor Java (de exemplu, NetBeans) includ, de asemenea, constructori de interfețe grafice cu utilizatorul îmbunătățite semnificativ.

C#, împreună cu Java, devine treptat popular pe mai multe sisteme de operare Bazat pe Linuxși BSD. Implementarea proiectului Mono a fost un proces nedureros din punct de vedere legal, deoarece limbajele CLR și C# sunt standardizate de Ecma și ISO și oricine le poate implementa fără a-și face griji cu privire la problemele legale. În același timp, trebuie menționat că o aplicație scrisă în mediul Windows poate avea probleme semnificative de rulare sub alt sistem de operare.

Aplicații server

În această arena, poate cele două limbi se apropie cel mai mult de a fi considerate concurenți. Java cu platforma sa J2EE (Java(2) Enterprise Edition) și C# cu ASP.NET concurează în domeniul creării de conținut și aplicații web dinamice.

Ambele limbi sunt utilizate pe scară largă și acceptate pe această piață, împreună cu suita de instrumente și produse suport disponibile pentru JavaEE și .NET.

Aplicatii mobile

J2ME (JavaME, Java(2) Micro Edition) are o bază foarte largă pe piețele de telefoane mobile și PDA, unde doar celor mai ieftine dispozitive le lipsește KVM (o mașină virtuală Java redusă pentru dispozitive cu resurse limitate). Programele Java, inclusiv multe jocuri, se găsesc peste tot.

Deși aproape toate telefoanele includ KVM, aceste capacități nu sunt utilizate foarte mult de majoritatea utilizatorilor. Aplicațiile Java de pe majoritatea telefoanelor constau de obicei în sisteme de meniu, jocuri mici etc. Aplicații complete pentru telefoanele mobile sunt rare.

înaltă tehnologie

C Sharp- Acest termen are alte semnificații, vezi C. Titlul corect al acestui articol este C#. Este afișat incorect din cauza limitări tehnice. C# Semantică: imperativ Clasa de limbaj: multi-paradigma: orientat pe obiecte,... ... Wikipedia

Visual J Sharp- Titlul corect al acestui articol Visual J#. Este afișat incorect din cauza limitărilor tehnice. Visual J# este un mediu de dezvoltare integrat creat de Microsoft pentru .NET Framework într-un limbaj asemănător Java. Mai ales... ... Wikipedia

F Sharp- Acest termen are alte semnificații, vezi F (sensuri). Titlul corect pentru acest articol F#. Este afișat incorect din cauza limitărilor tehnice. F# Clasă de limbaj: multi-paradigma: funcțional, orientat pe obiecte,... ... Wikipedia

Cânta Sharp- Titlul corect al acestui articol este Sing#. Este afișat incorect din cauza limitărilor tehnice. Sing# Clasa de limbaj: multi-paradigma: structural, imperativ, orientat pe obiecte, orientat pe evenimente, functional, ... ... Wikipedia

M.C. Sharp- MC# (a se citi „MC Sharp”, mcsharp), limbaj de programare C# multiprocesor. MC# este un limbaj de programare paralel orientat pe obiecte de nivel înalt pentru platforma .NET care acceptă crearea de programe care rulează în ... ... Wikipedia

Visual C Sharp

Visual C Sharp .NET - Microsoft Visual Studio Aspectul Visual Studio 2008 SP1 cu un program în C# în Windows Vista Tip Mediu de dezvoltare software... Wikipedia

ECMAScript- Clasa de limbaj: multi-paradigma: orientat pe obiecte, generic, functional, imperativ, orientat pe aspect, orientat pe evenimente, programare prototip A aparut in: 1995 Autor(i) ... Wikipedia