Сравнение C Sharp и Java

Материал из свободной русской энциклопедии «Традиция»
Перейти к навигации Перейти к поиску
Правильный заголовок этой статьи — Сравнение C# и Java. Он показан некорректно из-за технических ограничений.

В этой статье сравниваются языки программирования C# и Java — два очень похожих между собой современных языка со сборкой мусора и компиляцией при выполнении, произошедшие от языков Си и C++. Настоящая страница даёт обзор сходства и различия этих однотипных языков. Оба языка были тщательно спроектированы, и если в одном из них есть возможность, отсутствующая в другом, то это результат сознательного решения разработчиков. Таким образом, читателю следует избегать искушения «вести счёт» и вместо этого обратить внимание на причины, по которым было сделано то или иное решение.

Язык[править | править код]

Объектность[править | править код]

Оба языка — полностью объектно-ориентированные, с синтаксисом, похожим на синтаксис C++. Однако ни один из этих двух языков не является надмножеством C++. Оба они используют сборку мусора, а не явно задаваемое освобождение памяти. Оба включают в свой синтаксис механизмы синхронизации потоков.

И в Java, и в C# есть сильные и слабые ссылки на объекты. Java позволяет зарегистрировать слушатель (listener), который будет получать сообщения, когда ссылка подвергается сборке мусора, что даёт улучшение производительности WeakHashMap, которого нет в C#. Оба языка позволяют выполнять пользовательский код, когда объект подвергается сборке мусора, через специальные методы-финализаторы. Кроме того, C# (точнее, среда CLR) позволяет отменить выполнение финализатора для данного объекта методом GC.SuppressFinalize(obj) (напр., соединение SQL на файловом потоке). Это бывает полезным, поскольку финализация считается относительно дорогой операцией при сборке мусора, и объект с финализатором «живёт» дольше.

C# разрешает ограниченное использование указателей, которые проектировщики языков зачастую считают опасными. Подход C# в этом деле — требование ключевого слова unsafe при блоках кода или методах, использующих эту возможность. Это ключевое слово предупреждает пользователей такого кода о его потенциальной опасности. Оно также требует явного задания компилятору опции /unsafe, которая по умолчанию выключена. Такой «опасный» код используется для улучшения взаимодействия с неуправляемым API и иногда для повышения эффективности определённых участков кода.

Типы данных[править | править код]

Оба языка поддерживают идею примитивных типов (известных в C# как типы-значенияvalue types), и оба для трансляции примитивных типов в объектные обеспечивают их автоматическое «заворачивание» в объекты (boxing) и «разворачивание» (unboxing). У C# имеется больше примитивных типов, чем у Java, за счёт беззнаковых целых типов (unsigned), имеющихся парно ко всем знаковым, и специального типа decimal для высокоточных вычислений с плавающей запятой. В Java отказались от большинства беззнаковых типов ради простоты. В частности, в Java нет примитивного типа беззнакового байта.

Строки в обоих языках являются объектами (неизменяемыми), при этом поддерживается отдельный случай создания строк через строковые литералы.

C# позволяет создавать пользовательские типы-значения, используя ключевое слово struct. В отличие от экземпляров классов, экземпляры типов-значений создаются не на куче, а на стеке вызовов или в составе экземпляра объекта, в котором они объявлены, что в некоторых случаях повышает производительность кода. С точки зрения программиста они подобны классам, но с несколькими ограничениями: у них не может быть конструктора без параметров (но может быть конструктор с параметрами), от них нельзя наследовать и они не могут наследовать от других классов (но могут реализовывать интерфейсы).

Перечислимые типы в C# происходят от примитивных целочисленных типов. В этом языке допустимым значением перечислимого типа является любое значение лежащего в его основе примитивного, хотя для его присваивания может потребоваться явное приведение типа. Это позволяет комбинировать значения перечислимого типа побитовой операцией «или», если они являются битовыми флагами. В Java перечислимые значения, напротив, являются объектами. Единственные допустимые для них значения — те, что перечислены в объявлении типа. Для комбинации их вместе как флагов требуется специальный объект набора перечислений. В Java перечислимые типы позволяют задавать разные реализации методов для каждого значения. И в C#, и в Java перечисления могут преобразовываться в строки, но только в Java такое преобразование можно подгонять под себя (customize).

Массивы и коллекции[править | править код]

Массивы и коллекции тоже получили выражение в синтаксисе обоих языков, благодаря особой разновидности цикла for (цикл по коллекции, известный также как цикл foreach). В обоих языках массив является объектом класса Array, но в Java он не реализует какие-либо интерфейсы коллекций. В C# есть как настоящие многомерные массивы, так и массивы массивов, которые есть и в Java, а в C# обычно называются неровными, или ступенчатыми (jagged) массивами. Многомерные массивы всегда «прямоугольные» (говоря в двумерной терминологии), в то время как массивы массивов могут хранить строки разной длины (опять-таки в двумерном случае, в многомерном аналогично). Многомерные массивы ускоряют доступ к памяти (для них указатель разыменовывается только один раз), а неровные массивы работают медленнее, но экономят память, когда не все строки заполнены. Многомерные массивы требуют для своего создания лишь один вызов оператора new, а ступенчатые требуют явно выделять память в цикле для каждой строки.

Внутренние классы[править | править код]

Оба языка позволяют определить класс внутри класса. Однако Java поддерживает так называемые внутренние классы (inner classes): класс, объявленный внутри другого класса, может иметь доступ к нестатическим членам родительского класса, то есть «знает о this»; кроме того, внутри методов можно определять локальные классы, имеющие доступ по чтению к локальным переменным, и безымянные локальные классы, которые фактически позволяют создавать экземпляры объектов, перекрывающие методы своего класса.

Подход C# более традиционен и напоминает C++. Внутренние классы в C# имеют доступ только к статическим членам внешнего класса (в Java такие классы называются статическими внутренними), а для доступа к нестатическим членам нужно явно указывать экземпляр внешнего класса. Локальные внутренние классы в C# не поддерживаются (а из-за поддержки событийного программирования потребность в них гораздо меньше, чем в Java).

Обобщённое программирование[править | править код]

В обоих языках типы могут быть параметризованными, что поддерживает парадигму обобщённого программирования. Однако в Java для обобщённых классов используется так называемое затирание типов (type erasure): информация о специализирующем типе доступна только компилятору и во время выполнения отсутствует, а для рефлексии она доступна только для статических объектов. В .NET 2.0 же информация об обобщённых типах полностью сохраняется во время выполнения. Подход Java требует дополнительных проверок типа в программном коде, не гарантирует, что клиент кода будет следовать соответствию типов, и не обеспечивает рефлексии для обобщённых типов. Java не позволяет специализировать обобщённые типы примитивными (это можно сделать только заворачивая примитивные типы в классы), а C# обеспечивает обобщение как для ссылочных типов, так и для типов-значений, включая примитивные. Как в Java, так и в C# специализации обобщённого типа на разных ссылочных типах дают одинаковый код [1], но C# динамически генерирует оптимизированный код при специализации на типах-значениях (например, List<int>), что позволяет их хранить и извлекать из контейнеров без операций за- и разворачивания. В .NET 2.0 типовая безопасность (type safety) для обобщённых типов проверяется и на этапе компиляции, и на этапе загрузки виртуальной машиной, в то время как в Java она обеспечивается только во время компиляции (VM Java не знает об обобщённых типах), а на этапе выполнения требует прибегать к приведению типов. Среда выполнения .NET также может создавать динамически новые специализации обобщённых типов во время выполнения.

Обозначения и особые возможности[править | править код]

В Java есть специальный синтаксис импорта статических имён (import static), позволяющий использовать сокращённые имена некоторых или всех статических методов и переменных класса. В C# есть синтаксис статического класса (static class), ограничивающий класс только статическими методами, но нет возможности указывать только эти методы без явного задания класса каждый раз.

Специальные ключевые слова[править | править код]

Ключевое слово Возможность, пример использования
get, set Синтаксис C# поддерживает свойства.
out, ref C# поддерживает выходные параметры методов, позволяя возвращать несколько значений.
switch В C# оператор switch работает также на строках.
strictfp Java использует strictfp для гарантирования неизменности результатов операций с плавающей точкой на всех платформах.
checked, unchecked В C# выражения или блоки checked могут включать проверку арифметического переполнения во время выполнения.
using Ключевое слово using в C#'s обеспечивает ликвидацию или закрытие созданного объекта на выходе из блока кода:
using (StreamWriter file = new StreamWriter("test.txt"))
{
   file.Write("test");
}
goto C# поддерживает оператор перехода goto. Он может быть иногда полезным, хотя обычно рекомендуются более структурированные методы передачи управления (из-за чего от него и отказались в Java). Обычное использование ключевого слова goto в C# — передача управления на разные метки case в операторе switch.
switch(color)
{
   case Color.Blue: Console.WriteLine("Color is blue"); break;
   case Color.DarkBlue: Console.WriteLine("Color is dark"); goto case Color.Blue;
   // ...
}

Обработка событий[править | править код]

Java требует от программиста ручной реализации шаблона наблюдателя, хоть и обеспечивает некоторый синтаксический сахар в виде анонимных вложенных классов, что позволяет определить тело класса и тут же создать его экземпляр в одной точке кода. Эта возможность обычно используется для создания наблюдателей.

C# предоставляет обширную поддержку событийного программирования на уровне языка, включая делегаты .NET, мультикастинг, специальный синтаксис для задания событий в классах, операции для регистрации и разрегистрации обработчиков события, ковариантность делегатов и анонимные методы с полным набором семантики замыкания.

Замыкания предлагаются к включению в Java SE 7 [1]. Эти замыкания, как делегаты в C#, имели бы полный доступ ко всем локальным переменным в данной области видимости, а не только доступ для чтения к переменным, помеченным словом final (как с анонимными вложенными классами).

Перегрузка операций[править | править код]

C# включает большой набор синтаксических удобств, многие из которых, такие как перегрузка операций и задаваемое пользователем приведение типов, знакомы программирующим на C++. В нём также есть явная реализация методов интерфейса, что позволяет классу реализовывать методы интерфейса отдельно от собственных методов или давать разные реализации одноимённых методов, принадлежащих двум разным интерфейсам.

C# также включает так называемые индексаторы, которые можно считать особым случаем перегрузки операций (аналогичным перегрузке operator[] в C++), или параметризованными свойствами. Индексатор — это свойство с именем this[], которое может иметь один или более параметров (индексов); индексы могут быть объектами любого типа:

myList[4] = 5;
string name = xmlNode.Attributes["name"];
orders = customerMap[theCustomer];

Java не включает перегрузку операций, поскольку её злоупотребление может привести к трудночитаемому и трудно отлаживаемому коду. Вместе с тем отсутствие перегрузки в Java делает её малопригодной для некоторых математических программ.

Методы[править | править код]

В C# методы по умолчанию не являются виртуальными и должны для этого явно объявляться ключевым словом virtual. В Java, наоборот, все открытые методы, кроме статических, являются виртуальными. [2] Ключевое слово Java final является аналогом sealed в C# и позволяет запретить создание метода с такой же сигнатурой в производных классах. Виртуальность гарантирует нужное перекрытие для вызываемого метода, но при выполнении налагает некоторые расходы на вызовы, поскольку эти вызовы обычно не проходят инлайн-подстановку и требуют дополнительного обращения к таблице виртуальных методов. Однако некоторые реализации JVM, включая реализацию Sun, реализуют инлайн-подстановку наиболее часто вызываемых виртуальных методов.

C# требует явного объявления о намерении перекрыть (override) виртуальный метод в производном классе. Такое намерение описывается ключевым словом override. Если перекрытие не входит в намерения программиста, и требуется просто ввести новый виртуальный метод с тем же именеи и сигнатурой, заслоняющий (shadowing) старый, то тогда требуется другое ключевое слово, new. Если ни одно из этих слов не указано, то это ведёт к ошибке компиляции. В Java любой метод всегда виртуально перекрывает метод базового класса с теми же именем и сигнатурой, если он есть. Такое поведение потенциально опасно, если базовый класс создан другим разработчиком, и в новой его версии вводится такой же метод, который уже есть в производном классе; в этом случае существующий метод из производного класса перекроет вновь введённый метод в базовом, что не входит в намерения обоих разработчиков.

Условная компиляция[править | править код]

C#, в отличие от Java, поддерживает условную компиляцию с использованием директив препроцессора. В нём также есть атрибут Conditional, означающий, что указанный метод вызывается только тогда, когда определена данная константа компиляции. Таким путём можно вставлять в код, например, проверки допущений (assertion checks), которые будут работать только в отладочной версии, когда определена константа DEBUG. В стандартной библиотеке .NET таков метод Debug.Assert().

Java версий 1.4 и выше включает в язык возможность проверки допущений, включаемую во время выполнения.

Пространства имён и исходные файлы[править | править код]

Пространства имён C# больше напоминают C++. В отличие от Java, местонахождение файла с исходным текстом никак не связано с его пространством имён. Хотя, строго говоря, местонахождение исходных файлов в Java не обязательно отражает структуру каталогов пакета, но таково поведение по умолчанию.

Java требует, чтобы имя исходного файла точного соответствовало имени единственного общедоступного (public) класса, определённого в нём, в то время как C# позволяет в одном файле определять несколько общедоступных классов и не налагает никаких ограничений на имя файла, а также (в версии 2.0 и выше) позволяет разбить класс на два и более файла (ключевое слово partial).

Исключения[править | править код]

Java поддерживает проверяемые (checked) исключения, принудительно обеспечивая полную ловлю и обработку всех проверяемых исключительных ситуаций. Все проверяемые исключения, которые метод может выбросить, должны перечисляться в его объявлении при помощи ключевого слова throws. C# проверяемые исключения не поддерживает. Одни разработчики считают, что проверяемые исключения очень полезны для обеспечения хорошего стиля программирования. Другие, включая Андерса Хейлсберга, главного архитектора C#, возражают, что они в Java были в какой-то степени экспериментом и себя не оправдали [2] [3].

Один из аргументов против проверяемых исключений — то, что при их использовании изменение внутреннего кода функции может привести к выбросу новых исключений, что требует изменения в объявлении этой функции и всех других, её вызывающих. В конце концов для сохранения совместимости интерфейсов иногда стали просто объявлять функции как throws Exception. Однако даже в таком виде проверяемые исключения несут пользу, т.к. позволяют явно отследить, где именно должна происходить обработка этих исключительных ситуаций.

Более корректным способом сохранения совместимости интерфейса в Java считается такой — поймать нововведённое исключение, завернуть его в объявленное и снова выбросить. Например, если метод изменили так, что он начинает обращаться к базе данных вместо файловой системы, то он может сам ловить SQLException и выбрасывать вместо него вновь создаваемый IOException, поскольку пользователь метода не должен знать о деталях его внутренней реализации. Продуманным подходом считается изначально объявлять именно те исключения, которые придётся обрабатывать вызывающему коду. Скажем, если наш метод достаёт откуда-то издалека какие-то (не SQL) данные, то для него целесообразно объявить IOException. Если же наш метод оперирует SQL-запросами, то, вне зависимости от природы ошибки, он должен объявлять SQLException.

Надо отметить, что, хотя Java также полностью поддерживает и непроверяемые (unchecked) исключения, разработчики предпочитают пользоваться непроверяемыми исключениям только для проверки корректности входных данных и сохранности внутренних инвариантов - NullPointerException, IllegalArgumentException, ArrayIndexOutBoundsException, AssertionError и пр., тогда как события, обусловленные внешними причинами, используются проверяемые исключения - FileNotFoundException, EOFException, UnknownHostException и пр. Кстати, все три приведённых проверяемых исключения расширяют IOException, т.е. в декларации соответствущего метода достаточно написать throws IOException, не детализируя конкретный вид ошибки и не обобщая до Exception вообще.

Низкоуровневый код[править | править код]

Java Native Interface (JNI) позволяет программам вызывать из Java другой код. Однако JNI требует от вызываемого кода соблюдения специальных соглашений и налагает ограничения на использование типов и имён. Это означает, что между старым кодом и Java требуется дополнительный адаптирующий слой. Такой адаптирующий код должен писаться на C, C++ или других подобных языках. Выпускаются также специализированные библиотеки для взаимодействия Java с COM.

Технология Platform Invoke (P/Invoke), реализованная в .NET, предлагает ту же возможность, позволяя вызывать из C# внешний код, который Microsoft называет неуправляемым. Через атрибуты в метаданных программист может точно управлять передачей (маршалингом) параметров и результатов, избегая таким образом необходимости дополнительного кода адаптации. P/Invoke предоставляет почти полный доступ к процедурным API (таким, как Win32 или POSIX), но не даёт прямого доступа к библиотекам классов C++.

.NET Framework предоставляет также мост между .NET и COM, позволяя обращаться к COM-компонентам так, как если бы они были родными объектами .NET.

C# также позволяет программисту отключить нормальную проверку типов и другие возможности безопасности CLR, разрешая использование переменных-указателей при условии применения ключевого слова unsafe. JNI, P/Invoke и unsafe-код одинаково рискованны, чреваты дырами в безопасности системы и нестабильностью приложения. Преимуществом управляемого unsafe-кода над P/Invoke или JNI является то, что он позволяет программисту продолжать работать в знакомой среде C# для выполнения задач, которые при других методах потребовали бы вызова неуправляемого кода, написанного на другом языке.

Реализации[править | править код]

JVM и CLR[править | править код]

Java вездесуща во всевозможных операционных системах и средах. Существуют многочисленные реализации JVM, иногда с открытыми исходными кодами.

Java Webstart и апплеты обеспечивают удобное, лёгкое и безопасное средство распространения настольных приложений, причём эффективность её байткодового представления вкупе с агрессивными технологиями сжатия, такими как pack200, делают Java средством распространения сетевых приложений, неприхотливым к полосе пропускания.

C# тоже является кроссплатформенным стандартом. Его первичная платформа — Windows, но существуют и реализации для других платформ, самая значительная из которых — проект Mono.

Технология ClickOnce предлагает подобную же функциональность для Java Webstart, но она имеется только для клиентов Windows. Internet Explorer на Windows тоже умеет показывать элементы интерфейса .NET Windows Forms, что даёт апплетоподобную функциональность, но ограничено конкретным браузером.

Стандартизация[править | править код]

Развитие этих двух языков, и также их API, двоичных форматов и сред выполнения управляется по-разному.

C# определён стандартами ECMA и ISO, которые задают синтаксис языка, формат выполнимых модулей (извесный как CLI) и библиотеку базовых классов (Base Class Library, или BCL). Стандарты не включают многие новые библиотеки, реализованные Microsoft поверх стандартного каркаса, такие как библиотеки для баз данных, GUI и веб-приложений (Windows Forms, ASP.NET и ADO.NET). Однако Microsoft формально согласилось не преследовать в судебном порядке проекты сообщества за реализацию этих библиотек [4].

На сегодняшний день никакая составная часть среды Java не стандартизуется Ecma, ISO, ANSI или какой-либо другой сторонней организацией стандартов. В то время как Sun Microsystems сохраняет неограниченные исключительные юридические права на модификацию и лицензирование своих торговых марок Java, исходного текста и других материалов, Sun добровольно участвует в процессе, называемом Java Community Process (JCP), который позволяет заинтересованным сторонам предлагать изменения в любые Java-технологии Sun (язык, инструментарий, API) через консультации и экспертные группы. По правилам JCP, любое предложение по изменению в JDK, среде выполнения Java или спецификации языка Java может быть односторонне отвергнуто Sun, потому что для его одобрения требуется голос «за» со стороны Sun. От коммерческих участников JCP требует членских взносов, в то время как некоммерческие организации и частные лица могут участвовать в нём бесплатно.

Лицензия[править | править код]

В то время как «Java» — торговая марка Sun trademark, и только Sun может лицензировать имя «Java», существуют многочисленные свободные проекты, частично совместимые с Sun Java. Например, GNU Classpath и GNU Compiler for Java (GCJ) поставляют свободную библиотеку классов и компилятор, частично совместимые с текущей версией Sun Java[3]. В конце 2006 года Sun объявила, что весь исходный код Java, за исключением закрытого кода, на который они не сохраняют права, будет выпущен к марту 2007 года в качестве свободного программного обеспечения под видоизменённой лицензией GPL[4]. Sun в настоящее время распространяет свою HotSpot Virtual Machine и компилятор Java под лицензией GPL, но на стандартную среду выполнения Java сейчас нет свободной лицензии[5][6]. Поскольку Sun сохранит право собственности на свой исходный код Java, выпуск под лицензией GPL не запретит Sun распространять несвободные или неоткрытые версии Java, или давать на это лицензии другим[7].

C#, среда выполнения CLI и большая часть соответствующей библиотеки классов стандартизированы и могут свободно реализовываться без лицензии. Уже реализовано несколько свободных систем C#, в том числе Mono и DotGNU. В проекте Mono также реализованы многие нестандартные библиотеки Microsoft путём изучения материалов Microsoft, аналогично GNU Classpath и Java. Целью проекта Mono является избежать посягательств на какие-либо патенты или копирайты, и проект может свободно распространяться и использоваться под лицензией GPL[8]. Microsoft в настоящее время распространяет Shared source-версию своей среды выполнения .NET для некоммерческого использования [9].

Использование[править | править код]

Сообщество[править | править код]

Java построена на более открытой культуре с высокой конкурентностью фирм в различных областях функциональности. Хоть это полностью решает проблему независимости производителей ПО, но добавляет к языку дополнительную сложность. Для успешного использования библиотек и компонент надо знать не только Java, но и все разнообразные конкурирующие между собой оболочки и каркасы и разные особенности реализаций.

Несмотря на существование Mono, C# тесно привязывает разработчиков к платформе. Это сильно упрощает разработку и уже поэтому служит решением, хоть и может кому-то не нравиться.

Java следует более чистому подходу к разработке. Каркасы, построенные на Java, имеют тенденцию к большому количеству классов, взаимодействующих друг с другом, со многими слоями абстракции. Это придаёт каркасам значительную мощность, но изучение новой библиотеки может быть затруднено, и даже программа Hello world в некоторых случаях может оказаться сложной.

Подход C# более прагматичен. В дополнение ко вложенным уровням абстракции часто поставляются простые вспомогательные классы; в некоторых случаях уровни абстракции вообще не делаются.

Популярность и развитие[править | править код]

Java старше, чем C# и построена на большой и активной пользовательской базе, став lingua franca во многих современных областях информатики, особенно таких, где задействованы сети. Java доминирует в курсах программирования американских университетов и колледжей, и литературы по Java сегодня намного больше, чем по C#. Зрелость и популярность Java привели к большему числу библиотек и API на Java (многие из которых открытые), чем на C#.

В отличие от Java, C# — язык относительно новый. Microsoft изучила существующие языки, такие как Java и Дельфи, и изменила некоторые аспекты языка для лучшего соответствия нуждам некоторых типов приложений. С течением времени временное преимущество Java становится менее значимым.

В отношении Java можно услышать критику, что она медленно развивается, в ней не хватает некоторых возможностей, которые облегчают модные шаблоны программирования и методологии. Язык C# критикуют в том, что его разработчики, возможно, слишком спешат угодить сиюминутным течениям в программировании за счёт фокусировки и простоты языка. Очевидно, проектировщики Java заняли более консервативную позицию по добавлению крупных новых возможностей в синтаксис языка, чем в других современных языках — возможно, не желая привязать язык к течениям, которые в долгосрочной перспективе могут завести в тупик. С выпуском Java 5.0 эта тенденция во многом была нарушена, так как в ней ввели несколько крупных новых возможностей языка: цикл типа foreach, автоматическое заворачивание, методы с переменным числом параметров, перечислимые типы, обобщённые типы и аннотации (все они присутствуют и в C#).

C#, в свою очередь, развивается быстрее, гораздо слабее ограничивая себя в добавлении новых проблемно-ориентированных возможностей. Особенно эта тенденция проявилась в готовящейся к выпуску версии C# 3.0, в которой, например, появились SQL-подобные запросы. (Новые возможности при этом строятся так, чтобы язык оставался языком общего назначения. Подробнее о C# 3.0 см. в статье о C#). Проблемно-ориентированные дополнения к Java рассматривались, но, по крайней мере на сегодняшний день, были отвергнуты.

Рынок[править | править код]

С момента появления C# он постоянно сравнивается с Java. Невозможно отрицать, что C# и его управляемая среда CLR многим обязаны Java и ее JRE (Java Runtime Environment). Однако C# также приспособлен и к конструкциям, чаще существующим в языках типа C++, Дельфи (который спроектировал тот же Андерс Хейлсберг) и, в последних версиях C#, кое-что позаимствовал также из таких динамических скриптовых языков, как Руби.

Можно спорить, является ли разработка C# в какой-то степени результатом признания Майкрософтом того, что среда управляемого кода, где лидирует Java, имеет множество достоинств в растущем сетевом мире, особенно при появлении интернета на устройствах, отличных от персональных компьютеров, и при растущей важности сетевой безопасности. До создания C# Microsoft модифицировала Java(создав J++), с тем чтобы добавить возможности, работающие только на ОС Windows, нарушив таким образом лицензионное соглашение Sun Microsystems. Пока Microsoft находилась на второй фазе своей бизнес-стратегии, известной как <embrace, extend and extinguish>, развитие J++ было остановлено иском, поданным Sun'ом. Будучи лишённой возможности разрабатывать клон Java с нужными ей свойствами, Microsoft создала альтернативу, которая больше соответствовала их потребностям и видению будущего.

Несмотря на такое беспокойное начало, становится всё более очевидным, что два языка редко конкурируют друг с другом на рынке. Java доминирует в мобильном секторе и имеет много приверженцев на рынке веб-приложений. C# получил хорошее признание на рынке настольных приложений Windows и проталкивается Майкрософтом как основной язык приложений Windows. Благодаря ASP.NET, C# также является игроком и на рынке веб-приложений.

Настольные приложения[править | править код]

Java иногда обвиняют в том, что она много обещает и мало даёт, когда речь заходит о настольных приложениях. Хоть её оконные библиотеки AWT (Abstract Windowing Toolkit) и Swing могут похвастаться обилием возможностей (стоит также отметить SWT разработанную фондом Eclipse), Java пришлось побороться, чтобы утвердиться на рынке настольных приложений. Её строгая приверженность принципу «пишем один раз, используем везде» затрудняет использование по максимуму специфических возможностей и режимов работы в каждой конкретной настольной системе. В результате написанные на Java настольные приложения часто выглядят как «чужие» на той платформе, на которой они выполняются.

Sun Microsystems, по мнению некоторых, также медлила с продвижением Java в среду разработчиков и пользователей, чтобы сделать её привлекательным выбором для настольных приложений. Даже такие технологии, как Java Web Start, у которых мало соперников среди языков и платформ, продвигались слабо.

Выпуск Java версии 6.0, предполагаемый в 2006 году, заново фокусируется на настольном рынке — с обширным набором новых и интересных инструментов для лучшей и более тесной интеграции с настольной средой.

Многие открытые и свободные операционные системы также отказываются включить какую-либо среду Sun Java Runtime Environment, поскольку Sun Microsystems ещё не лицензировала легально совместимую версию для общественного достояния.[6][10][11] Многие из нынешних пользовательских лицензионных соглашений Sun, касающихся Java, определяют многое из платформы Java как коммерческую тайну[6] и бессрочно запрещают конечному пользователю делать вклад в среду Java третьих сторон. Некоторые из этих положений могут измениться, если Sun изменит лицензию Java на GPL, о чем она уже объявляла как о намерении.

C# недавно стал популярным на нескольких операционных системах на основе Linux и BSD.[12][13][14] Реализация проекта Mono была юридически безболезненным процессом, поскольку CLR и язык C# стандартизированы Ecma и ISO, и любой может их реализовывать, не беспокоясь о правовой стороне дела[15].

Серверные приложения[править | править код]

На этой арене, возможно, два языка наиболее близки к тому, чтобы считаться конкурентами. Java с её платформой J2EE (Java(2) Enterprise Edition) и C# с его ASP.NET соперничают в области создания динамического веб-контента и приложений.

На этом рынке широко используются и поддерживаются оба языка, вместе с комплектом инструментов и сопровождающих продуктов, имеющихся для JavaEE и .NET.

Мобильные приложения[править | править код]

J2ME (JavaME, Java(2) Micro Edition) имеет очень широкую базу на рынках мобильных телефонов и КПК, где только самые дешёвые устройства лишены KVM (урезанная Java Virtual Machine для устройств с ограниченными ресурсами). Программы на Java, включая множество игр, встречаются повсеместно.

В то время как почти все телефоны включают в себя JVM, эти возможности используются большинством пользователей не очень интенсивно. Приложения Java на большинстве телефонов обычно состоят из систем меню, небольших игр и т. д. Полноценные приложения для мобильных телефонов редки.

На рынке смартфонов и КПК быстро набирает силу Windows Mobile, она же становится предпочтительной платформой для написания тяжёлых бизнес-приложений. Windows Mobile основана на платформе Windows CE и использует .NET Compact Framework (.NETCF) — подмножество полной версии .NET Framework с дополнительной функциональностью для мобильных устройств.

Передовые технологии[править | править код]

Java принята в качестве официального программного средства для использования в следующем поколении стандарта DVD, Blu-ray, через интерактивную платформу BD-J. Это значит, что такое интерактивное содержимое, как меню, игры, скачивания и т.д., на всех дисках DVD Blu-ray будет создаваться на платформе Java.

Примечания[править | править код]