C # vs genéricos Java

votos
105

Ouvi dizer que a implementação Java de genéricos não é tão boa como a implementação C #. Em que a sintaxe é semelhante, o que é que é inferior sobre a implementação Java, ou é um ponto de vista religioso?

Publicado 10/12/2008 em 05:12
fonte usuário
Em outras línguas...                            


3 respostas

votos
137

ligação de streloksi faz um ótimo trabalho de quebrar as diferenças. O resumo rápido e sujo, porém, é ...

Em termos de sintaxe e uso. A sintaxe é praticamente o mesmo entre as línguas. Algumas peculiaridades aqui e ali (principalmente em restrições). Mas, basicamente, se você pode ler um, você provavelmente pode ler / usar o outro.

A maior diferença, porém, é na implementação.

Java usa a noção do tipo de apagamento para implementar genéricos. Em suma as classes subjacentes compilado na verdade não são genéricos. Eles compilar para baixo para Object e moldes. Com efeito genéricos Java são um artefato tempo de compilação e pode ser facilmente subvertido em tempo de execução.

C #, por outro lado, em virtude da CLR, implementar genéricos todos eles caminho até o código de byte. O CLR levou várias alterações significativas a fim de apoiar os genéricos em 2,0. Os benefícios são melhorias de desempenho, verificação de tipo de segurança profunda e reflexão.

Mais uma vez o fornecido ligação tem muito mais em colapso profundidade Encorajo-vos a ler

Respondeu 10/12/2008 em 05:26
fonte usuário

votos
31

A diferença se resume a uma decisão de projeto pela Microsoft e Sun.

Genéricos em Java é implementada através de eliminação de tipo pelo compilador, o que significa que a verificação de tipo ocorre em tempo de compilação, e as informações de tipo é removido. Esta abordagem foi adoptada para manter o código legado compatível com novos genéricos de código usando:

A partir dos tutoriais Java, Generics: Tipo Erasure :

Quando um tipo genérico é instanciado, o compilador traduz esses tipos por uma técnica chamada eliminação de tipo - um processo onde o compilador remove todas as informações relacionadas a digitar parâmetros e argumentos de tipo dentro de uma classe ou método. Tipo de apagamento permite que os aplicativos Java que usam genéricos para manter a compatibilidade binária com as bibliotecas Java e aplicativos que foram criados antes de genéricos.

No entanto, com genéricos em C # (.NET) , não existe qualquer tipo de apagamento pelo compilador, e os de tipo verificações são realizadas durante o tempo de execução. Isso tem suas vantagens que o tipo de informação é preservada no código compilado.

De Wikipedia:

Esta escolha de design é alavancado para fornecer funcionalidade adicional, como permitir a reflexão com a preservação de tipos genéricos, bem como aliviar algumas das limitações de apagamento (tais como sendo incapaz de criar matrizes genéricas). Isto também significa que não há desempenho atingido por moldes de tempo de execução e conversões de boxe normalmente caros.

Ao invés de dizer ".NET genéricos é melhor do que os genéricos Java", deve-se olhar para a diferença na abordagem para implementar genéricos. Em Java, parece que preserva a compatibilidade era uma prioridade, enquanto na .NET (quando introduzido na versão 2.0), a perceber os benefícios da utilização de genéricos foi uma prioridade mais elevada.

Respondeu 10/12/2008 em 05:24
fonte usuário

votos
4

Também encontrado esta conversa com Anders Hejlsberg que pode ser interessante também. Para resumir os pontos que Anders Hejlsberg feitos com algumas notas adicionais: genéricos Java foram feitos para o máximo de compatibilidade com JVM existente que levou a algumas coisas estranhas contra a implementação você vê em C #:

  • Digite implementação forças de apagamento para representar cada valor parametrizada genérico como Object. Enquanto compilador fornece moldes automáticas entre Objecte mais tipo específico, ele não remove o impacto negativo dos modelos de tipo e de boxe no desempenho (por exemplo, Objecté convertido em tipo específico MyClassou inttinha de ser encaixotado Integer, o que seria ainda mais grave para C # /. NET se seguiu tipo abordagem apagamento, devido a tipos de valor definido pelo utilizador). Como disse Anders: "você não obter qualquer da eficiência de execução" (que os genéricos reificadas permitir que em C #)

  • Tipo de apagamento disponibiliza informações em tempo de compilação não é acessível durante a execução . Algo que costumava ser List<Integer>torna-se apenas um Listcom nenhuma forma de recuperar parâmetro de tipo genérico em tempo de execução. Isso torna difícil construir reflexão ou de geração de código dinâmico cenários em torno de genéricos Java. Mais recente SO resposta mostra uma maneira de contornar isso através de classes anônimas. Mas, sem truques, algo como gerar código em tempo de execução por meio de reflexão que recebe elementos de uma instância de coleção e coloca-lo para outra instância de coleção pode falhar em tempo de execução durante a execução de código gerado dinamicamente: reflexão não ajuda com captura de incompatibilidade na List<Double>comparação List<Integer>nestas situações .

Mas +1 para a resposta ligando para Jonathan Pryor post .

Respondeu 10/12/2008 em 13:26
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more