Спиши, но не точь в точь
Спиши, но не точь в точь

Disclamer: Автор не претендует на глубокие познания в Java или C#. Но очень хотелось разобраться в истории происхождения данного мема. Если заметите неточности, то пишите в комментариях, буду рад исправить.

Небольшая историческая справка

1996 год. Джеймс Гослинг со своей командой выпускают язык, над которым усиленно работали последние 5 лет. Этим языком был Java, который стал большим успехом для компании и получил широкое распространение. И в течении четырех лет всё было безмятежно, язык совершенствовался, комьюнити увеличивалось, проблемы решались.

Но вот наступает лето 2000 года. Презентация Microsoft. Демонстрируется продукт над которым они работали последние годы. Этим продуктом был .NET Framework, в рамках демонстрации которого показывают C#.

И смотря на его синтаксис у многих возникли невольные ассоциации с Java.

«Вы, ребятки (из Microsoft), все еще не понимаете, это своего рода Java с удаленными надежностью, производительностью и безопасностью»

Джеймс Гослинг - создатель Java

Создатель C# не оставил это без внимания и отметил, что

C# «не является клоном Java» и «гораздо ближе к C++» по своему дизайну

Андрес Хейлсберг - создатель Turbo Pascal, Delphi, C# и TypeScript

Но несмотря на возражения, шлейф клона Java за C# остался до сих пор. Давайте же попробуем понять какие моменты в C# были явно «вдохновлены» Java

C# вдохновляется Java

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

// Класс на Java

class Person {
    private int age;
    private String name;

    public Person(int age, String name) {
        this.name = name;
        this.age = age;
    }

    public void sayHello() {
        System.out.println("Hello, my name is " + name +
            "and I`m " + age + "years old.");
    }
}
// Класс на C#

using System;

class Person {
    private int age;
    private string name;

    public Person(int age, String name) {
        this.name = name;
        this.age = age;
    }

    public void sayHello() {
        Console.WriteLine("Hello, my name is " + name +
            "and I`m " + age + "years old.");
    }
}

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

Алгоритм сборки мусора в Java
Алгоритм сборки мусора в Java
Алгоритм сборки мусора в C#
Алгоритм сборки мусора в C#

Механизм рефлексии. Рефлексия — это механизм исследования данных о программе во время её выполнения. Этот механизм в присутствовал еще в языках ассемблера, но Java привнесла его в высокоуровневые языки, переработав подход к ним. Что взял на вооружение в том числе и C#

// Рефлексии в Java

import java.lang.reflect.Method;

public class GetMethodsExample {
    
    public static void main(String...args) {
        Class<GetMethodsExample> c = GetMethodsExample.class;
        Method[] methods = c.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
    }
    
    public int calcInt(int i) {
        return 0;
    }
    
    public void doSomething() {}
    
    public static void aStaticMethod(String s) {}
    
    private void aPrivateMethod() {}
}
// Рефлексии в C#

using System.Reflection;

public class GetMethodsExample {

    public static void Main() {
        MethodInfo[] methodInfos = Type.GetType("GetMethodsExample").GetMethods();
        foreach(MethodInfo methodInfo in methodInfos) {
            Console.WriteLine(methodInfo.Name);
        }

    }

    public int calcInt(int i) {
        return 0;
    }

    public void doSomething() {}

    public static void aStaticMethod(String s) {}

    private void aPrivateMethod() {}
}

Java вдохновляется C#

Но не все так однозначно и впоследствии некоторые решения из C# перетекли в Java.

LINQ. Language Integrated Query — проект Microsoft по добавлению синтаксиса языка запросов, напоминающего SQL, в языки программирования платформы .NET Framework. Впервые LINQ появился в C# в 2007 году и лишь спустя 7 лет подобный функционал появился в Java в виде Streams API 

// LINQ

class Program {

    static void Main() {
        var numbers = new List<int> {1, 2, 3, 4, 5 };
        var evenNumbers = numbers.Where(n => n % 2 == 0);
        var squares = numbers.Select(n => n * n);
        var sum = numbers.Aggregate((a, b) => a + b);
    }
}
// Streams API

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

public class Example {

    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        Stream<Integer> evenNumbers = numbers.stream().filter(n -> n % 2 == 0);
        Stream<Integer> squares = numbers.stream().map(n -> n*n);
        Optional<Integer> sum = numbers.stream().reduce((a, b) -> a + b);
    }
}

Атрибуты позволяют помечать функции, свойства, классы, методы и т. д. Они появились в C# в 2002 году.  В Java такая возможность была названа аннотациями. Несколько встроенных аннотаций появилось в Java в 2004 году, возможность создания собственных аннотаций с различными полями появилась аж в 2013

// Атрибуты в C#

class Program {

    [Obsolete("Method1 is deprecated, please use Method2 instead.")]
    public void Method() {
        Console.WriteLine("Устаревший метод");
    }

    public void Method2() {
        Console.WriteLine("Актуальный метод");
    }

    public static void Main() {
        new Program().Method();
    }
}
// Атрибуты в Java

public class Program {
    /**
     * @deprecated
     * Method1 is deprecated, please use Method2 instead
     */
    @Deprecated
    public void Method1() {
        System.out.println("Устаревший метод");
    }
    public void Method2() {
        System.out.println("Актуальный метод");
    }

    public static void main(String[] args) {
        new Program().Method1();
    }
}

Делегаты. Делегат - класс, который позволяет хранить в себе ссылку на метод с определённой сигнатурой (порядком и типами принимаемых и типом возвращаемого значений) произвольного класса. Они были в C# с момента релиза. В 2014 году в Java были добавлены делегаты в виде функциональных интерфейсов

// Делегаты

using System;

delegate int Adder(int a, int b);

class Program {

    static void Main(string[] args) {
        Adder adder = (a, b) => a + b;
        int result = adder(5, 10);
        Console.WriteLine(result);
    }
}
// Функциональные интерфейсы

@FunctionalInterface
interface Adder {
    int add(int a, int b);
}

public class Main {

    public static void main(String[] args) {
        Adder adder = (a, b) -> a + b;

        int result = adder.add(5, 10);
        System.out.println(result);
    }
}

Так каков итог?

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

Всем позитива!

Комментарии (18)


  1. gsaw
    10.06.2024 14:18

    Если бы С# изначально имел мультиплатформенную реализацию, если бы долго не игнорировали mono и open source, а сразу подхватили бы, то может быть и вышло что то, как с typescript к примеру, может и захватили бы рынок. До 8-ки java была в отстающих, медленно развивалась. А сейчас имхо для C# поздновато стало конкурировать с java и python. Недавно попросили человека сделать проект небольшой, он почему то серверную часть на C# сделал. Все с него потом удивлялись. Скорее экзотика, чем что то распространённое. Где потом искать людей на обслуживание. Брать человека со знанием C# ради одного проекта?


    1. breninsul
      10.06.2024 14:18
      +5

      C# очень популярен в игровой разработке (Unity).

      Ну и бизнес-приложения тоже пишут не редко, слышал там нормальные ORM есть, в отличие от Java.

      Впрочем, в самой Java с появление Kotlin тоже смысла не много


      1. ris58h
        10.06.2024 14:18
        +10

        Заход на Java-бинго с одного комментария.

        Забыли уточнить, что она ещё и тормозит.


    1. xemos
      10.06.2024 14:18
      +12

      В смысле где брать людей? На рынке, c# популярный язык


    1. Gromilo
      10.06.2024 14:18
      +6

      Мне кажется, они близнецы-братья. Просто кто к чему больше привык. У нас бы странно посмотрели на человека, который бэкенд на java написал.

      По рейтингу почти одно и то же.


      1. ris58h
        10.06.2024 14:18

        Понять бы ещё сколько из этой доли приходится на Unity, например. Уверен, что большая часть Java приходится на бэкэнд.


        1. lumini
          10.06.2024 14:18
          +7

          На hh: 1 450 вакансий «Java backend», 1 326 вакансий «asp.net OR C# backend», 257 вакансий «unity C#» .


        1. Proscrito
          10.06.2024 14:18

          С 2002 года пишу под дотнет. 23й год уже. Техлид, все дела, каких только проектов не видел. Больше всего конечно бэкэнд. Это основная часть рынка дотнет. С огромным отрывом от всех остальных. Ну еще есть очень востребованные фуллстэк, которые к своему апи могут сваять несложный фронт на реакте или ангуляре, в одно лицо. Удобно.

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

          Про РФ не знаю.


          1. ris58h
            10.06.2024 14:18

            Это всё хорошо, но к чему эти рассуждения про .NET? Мы популярность C# обсуждаем.


            1. Proscrito
              10.06.2024 14:18

              Это конкретно ответ на "Понять бы ещё сколько из этой доли приходится на Unity".


      1. DieSlogan
        10.06.2024 14:18

        Да, одного усыновила семья, а другой, после, смерти папы, перешёл под опеку к не совсем доброму дядюшке :)


    1. Jhayphal
      10.06.2024 14:18
      +1

      Это в РФ Java так сильно распространена. В Украине большинство более менее новых проектов на C#. Java в основном там, где так исторически сложилось. Более того, многие работают на забугорные компании, и в основном они на C#.

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


      1. DieSlogan
        10.06.2024 14:18

        Очень много проектов написано в нулевые. А тогда, если хочешь серьёзный проект, кроссплатформ иили юникс, то был С или Джава. Собственно и всё. Perl использовал неудобный CGI-BIN, но был медленнее С. А PHP и Python был уделом веб-сайтов и мелких приложений. Другие языки занимали очень малую долю рынка.

        Я прекрасно помню, как перейдя PHP на Java я был впечатлён фреймворком, ведь в 2007 PHP представлял собой раздолье для любителей велосипедов, каждый сам себе фреймворк.

        А вот сейчас на рынке богатый выбор инструментов и многие знакомые труджависты, тихо-тихо мигрируют куда-то, где им более комфортно.


    1. DieSlogan
      10.06.2024 14:18
      +2

      Хм, а мне казалось, что она развивалась до восьмёрки, пока был Sun. А с Ораклом у неё всё стало походить на ИБД.

      У C# была одна большая проблема, это Стив Балмер с его идиотским видением прекрасного будущего. Такого CEO никому не пожелаешь.

      А что касается функционала Java. Например, Streams, которые не так уж давно завезли в яву, это LINQ в C#, который появился там в году 2008-ом. В мире дотнета как бы само собой разумеется, что C# не просто язык, он в дотнете, которому требуются фпеймворки на все случаи жизни. И всё это более-менее целостное. А в J2EE есть только сервлеты, а обычно её функционал в Spring Boot, Hibernate, Jackson, GSON и т.п. Всё это не целостное, к тому же. Привет тем, кто при использовании log4j вынужден ставить адаптер для Slfj. И такого много. Например JSP/JSF выдают ошибки привязки модели в рантайме, тогда как в Razor это будет ошибка компиляции, а хочешь логгер, вот тебе интерфейс ILogger и не балуй.

      А беда с датами? Прекрасно помню свои эмоции, когда только подружил Calendar с XMLGregorianCalendar, вычистил из проекта Date и тут вышла Java 8, с их кучей классов для даты. Я искренне не понимаю, почему Date они сделали Deprecated а Calendar нет. И почему создали Calendar, когда можно было доработать Date и отменить deprecated. И это просто показательный случай, просчёты не исправляются, их консервируют.

      В дотнете нет выбора GC, он по-умолчанию и великолепно работает. А если вы хотите прекрасный GC в Java, то он платный. И это не весело, то есть ребята пишут хороший GC, а потом убирая из него часть отдают бесплатно, а полноценный продают за деньги. Разумеется им не выгодно революуионно менять язык, тогда их GC+ надо будет дорабатывать.

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

      А иногда просто за дураков держат как в случае с перегрузкой операторов ==,! =и т.д., заявляя, что это будет путать, все уже привыкли не сравнивать так а использовать equals.


      1. gsaw
        10.06.2024 14:18
        +1

        Да где я написал, что Java лучше? Я имел ввиду, что сишарп мог бы захватить мир, и проморгали шанс. В нашей местности , в нашей компании на Java больше проектов, проще найти специалистов.


        1. DieSlogan
          10.06.2024 14:18
          +2

          Да я так, болью за 6 лет на Java поделился.

          Не знаю, проморгал ли? Сейчас Java в роли догоняющего.

          А насчёт кадров на Java, на моей совести 5 закоренелых джавистов, которых я переучил и они сейчас говорят:"Java? Нееет."

          Я люблю иногда захаживать на репозитарий Microsoft, посмотреть проекты новые какие. Я уже писал в другой теме, но у них там отборная дурь. Потому что в трезвом уме некоторые проекты и не придумать. Чего только стоят компиляторы с dotnet и TS в Ардуино машинные коды. Или рантайм позволяющий прямое двустороннее взаимодействие с nodeJS. Это помимо недавно прогремевшего Aspire и Garnet.

          У ребят там есть задор, они соревнуются с Go и nodeJS за пальму первенства. Пока такой движ, говорить о прошедшемне приходится.


  1. eugeneyp
    10.06.2024 14:18
    +7

    Там всё было гораздо интереснее:

    1) Microsoft JVM для Java 1 был самой удачной и наиболее используемой в Windows
    2) MS добавляет поддержку OCX как часть JVM
    3) Между Sun и MS возникает конфликт т.к. Java код начинает работать не везде.
    4) MS получает к себе А.Хейлсберга
    5) MS Выпускает J# как Java 2.0
    6) MS Выпускает C#

    Ну там еще по пути потерялись разные события, которые тоже могли повлиять на рождение и развитие C# и Java.

    До Java было понятие PCODE которое использовали VisualBasic dBase (FoxPro). Это не совсем VM в чистом виде но при этом и не скомпилированный код.


    1. DieSlogan
      10.06.2024 14:18

      Она была не просто более удачная, она была заметно быстрее и они ещё туда Windows Foundation Classes завезли, для создания пользовательского интерфейса.

      Только, там сначала Visual J++ был.