Menu

C# vs Java: sintaxe, runtime, genéricos, LINQ e qual aprender

C# e Java se parecem e resolvem problemas parecidos. As diferenças reais estão em propriedades, tipos de valor, genéricos, LINQ versus streams, async, exceções e nos ecossistemas em volta. Uma comparação lado a lado com código.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

C# e Java são parentes próximos. As duas são linguagens com tipagem estática, orientadas a objetos, com garbage collector e sintaxe no estilo C, as duas compilam para bytecode de uma máquina virtual e as duas são usadas em grandes sistemas de backend. C# foi lançada em 2002 em parte como a resposta da Microsoft ao Java, e em duas décadas as duas pegaram recursos uma da outra (lambdas, genéricos, records, pattern matching). Um desenvolvedor que conhece uma consegue ler a outra quase imediatamente.

As diferenças que importam no dia a dia são menores e mais específicas. Esta página passa por elas com código: trechos em C# que você pode executar, e Java em blocos estáticos para comparação.

Visão geral

C#Java
Criada porMicrosoft (2002)Sun Microsystems (1995), hoje Oracle
RuntimeCLR (.NET), compila IL para código nativoJVM, compila bytecode para código nativo
PlataformasWindows, Linux, macOSWindows, Linux, macOS
PropriedadesEmbutidas: public int Age { get; set; }Métodos getter e setter
Tipos de valor definidos pelo usuáriostructAinda não (Project Valhalla)
GenéricosReificados: os tipos existem em tempo de execuçãoApagados: os tipos são removidos depois da compilação
Consultar coleçõesLINQAPI de Streams
Asyncasync / awaitVirtual threads (Java 21), CompletableFuture
Exceções checadasNãoSim
Sobrecarga de operadoresSimNão
Segurança contra nullTipos de referência anuláveis (C# 8)Optional<T>, anotações
Principais usosJogos na Unity, ASP.NET Core, desktop Windows, AzureBackends corporativos, Android, big data

Sintaxe: quase igual

Classes, métodos, if, for, while, switch, try/catch se leem quase da mesma forma. As diferenças visíveis são as convenções de nomes e algumas palavras-chave: métodos em C# usam PascalCase (ToUpper, WriteLine), métodos em Java usam camelCase (toUpperCase, println); C# escreve string e bool, Java String e boolean; herança é class Dog : Animal em C# e class Dog extends Animal em Java.

// Java
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        names.add("Ana");
        names.add("Ben");
        for (String n : names) {
            System.out.println(n.toUpperCase());
        }
    }
}

Saída:

ANA
BEN

C# também compara strings por valor com ==, o que elimina um dos bugs clássicos de iniciante em Java: lá, == entre dois objetos String compara referências, então duas strings iguais montadas em tempo de execução (lidas da entrada, concatenadas) podem ser consideradas diferentes.

Propriedades em vez de getters e setters

Classes Java expõem estado por métodos getName() e setName(), normalmente gerados por uma IDE ou pelo Lombok. C# tem propriedades: membros que se leem como campos, mas executam código.

// Java
public class Product {
    private double price;
    public double getPrice() { return price; }
    public void setPrice(double price) {
        if (price < 0) throw new IllegalArgumentException("negative");
        this.price = price;
    }
}

Saída:

Mug: 9.50

O inicializador de objeto new Product { Name = ..., Price = ... } define propriedades logo depois da construção. Os records do Java (Java 16) cobrem o caso de dados imutáveis; C# também tem records (C# 9), além de propriedades para todo o resto.

Tipos de valor: structs

Em Java, todo tipo definido pelo usuário é um tipo de referência guardado no heap; só os oito primitivos (int, double, ...) são valores. C# permite definir seus próprios tipos de valor com struct. Uma struct é copiada na atribuição e pode ficar embutida em arrays e em outros objetos, sem uma alocação separada no heap.

Saída:

a = (1, 2)
b = (99, 2)
1000

Isso importa em jogos e em código numérico, em que milhões de objetos pequenos pressionariam o garbage collector. Veja structs.

Genéricos: reificados vs apagados

Java apaga os argumentos de tipo genéricos em tempo de compilação: em tempo de execução, uma List<Integer> é só uma List, e List<int> não é permitido (você recebe objetos Integer com boxing). C# mantém os argumentos de tipo em tempo de execução, então List<int> guarda ints puros e o código pode perguntar o que T é.

Saída:

3 items of type Int32
1 items of type String
List`1

typeof(T) e new T() funcionam porque o runtime conhece T. Em Java os dois são erros de compilação, e a solução usual é passar um objeto Class<T> adiante.

LINQ vs streams

As duas linguagens têm uma API fluente para filtrar e transformar coleções. A do Java é a API de Streams (Java 8); a de C# é o LINQ (C# 3), que também tem uma sintaxe de consulta e funciona com bancos de dados por meio do Entity Framework.

// Java
List<String> expensive = products.stream()
    .filter(p -> p.getPrice() > 20)
    .sorted(Comparator.comparing(Product::getPrice))
    .map(Product::getName)
    .collect(Collectors.toList());

Saída:

Lamp, Chair
Total: 126

As operações se correspondem uma a uma (filter é Where, map é Select, collect(toList()) é ToList()), e as versões em C# não precisam de stream() nem de coletor. Os objetos new { Name = ..., Price = ... } são tipos anônimos, que não têm equivalente direto em Java.

Async e concorrência

C# introduziu async/await em 2012: um método async retorna uma Task, e await o suspende sem bloquear uma thread. JavaScript, Python e Rust adotaram depois as mesmas palavras-chave. Java seguiu outro caminho: cadeias de CompletableFuture e, desde o Java 21, virtual threads que tornam barato o código bloqueante comum.

// C#
async Task<string> LoadAsync(HttpClient http, string url)
{
    string body = await http.GetStringAsync(url);
    return body.Substring(0, 100);
}
// Java 21 with virtual threads: plain blocking code on a cheap thread
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    executor.submit(() -> client.send(request, BodyHandlers.ofString()));
}

As duas abordagens escalam para muitas requisições concorrentes. C# deixa a assincronia visível nas assinaturas dos métodos; Java a esconde no runtime.

Exceções, operadores e diferenças menores

  • Exceções checadas. Java obriga um método a declarar ou capturar certas exceções (throws IOException). C# não tem exceções checadas.
  • Sobrecarga de operadores. C# permite que tipos definam +, ==, < e parecidos, e é por isso que a aritmética com decimal e DateTime se lê naturalmente. Java não permite (BigDecimal.add).
  • Virtual por padrão. Métodos Java podem ser sobrescritos a menos que sejam final; métodos C# precisam ser marcados como virtual para poderem ser sobrescritos, e a sobrescrita precisa dizer override.
  • Métodos de extensão. C# pode adicionar métodos a tipos existentes ("text".IsPalindrome()); Java não.
  • Tipos de valor anuláveis. int? em C# é um int que pode ser null; Java usa o Integer com boxing.
  • Tipos sem sinal. C# tem uint, ulong, ushort e um byte sem sinal; o byte do Java tem sinal e, fora o char de 16 bits, Java não tem tipos inteiros sem sinal.

Ecossistema, vagas e qual aprender

O ecossistema do Java é maior no mundo open source de servidores: Spring, Kafka, Spark, Hadoop, Elasticsearch e a maioria dos projetos Apache são em Java. Apps Android são escritos em Kotlin ou Java. C# tem a pilha mais integrada: um único fornecedor mantém a linguagem, o runtime, o framework web (ASP.NET Core), o ORM (Entity Framework) e a IDE principal (Visual Studio), e a Unity a coloca no centro do desenvolvimento de jogos.

As duas linguagens têm mercados de trabalho grandes, e o equilíbrio entre elas depende da região e do setor. C# é forte em empresas construídas sobre Microsoft e Azure, em software de finanças e saúde e em estúdios de jogos.

Escolha C# se você quer fazer jogos na Unity, construir apps desktop para Windows ou trabalhar em uma empresa .NET. Escolha Java se o seu alvo é Android, big data ou uma empresa cujo backend roda na JVM. Qualquer uma das duas ensina os conceitos de que você precisa para a outra: classes, interfaces, genéricos, coleções, exceções e um runtime com garbage collector.

Perguntas frequentes

C# é parecido com Java?

Sim, muito. As duas são linguagens com tipagem estática, orientadas a objetos, com garbage collector e sintaxe no estilo C, que compilam para bytecode de uma máquina virtual. Um desenvolvedor Java consegue ler C# no primeiro dia. As diferenças estão nos detalhes: C# tem propriedades, tipos de valor definidos pelo usuário, genéricos reificados, LINQ e async/await, enquanto Java tem exceções checadas e um ecossistema open source de servidor maior.

Devo aprender C# ou Java primeiro?

Escolha pelo que você quer construir. C# para jogos na Unity, apps desktop para Windows e empresas construídas sobre Microsoft e Azure. Java para Android (junto com Kotlin), grandes backends corporativos e ferramentas de big data como Kafka e Spark. As linguagens são próximas o bastante para que trocar depois leve semanas, não meses.

C# é mais rápido que Java?

Elas estão na mesma classe de desempenho: as duas fazem compilação JIT para código nativo e usam garbage collectors geracionais. C# dá mais controle de baixo nível com structs, Span<T> e genéricos sobre tipos de valor sem boxing, o que ajuda em código com muitas alocações. Em cargas web típicas, o framework e o banco de dados importam muito mais que a linguagem.

C# tem exceções checadas como Java?

Não. Em C#, nenhum tipo de exceção precisa ser declarado ou capturado; a assinatura de um método não lista o que ele lança. Os projetistas concluíram que exceções checadas levavam a blocos catch vazios e a assinaturas frágeis. Você documenta as exceções com comentários XML /// <exception>.

Qual tem mais vagas, C# ou Java?

As duas têm mercados de trabalho grandes, e qual tem mais vagas depende do país e do setor, então confira os anúncios onde você quer trabalhar. C# é forte em empresas corporativas que usam Microsoft, finanças, saúde e estúdios de jogos; Java em grandes bancos, telecomunicações, backends de e-commerce e Android.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR