He oído que la implementación de Java de Generics no es tan buena como la implementación de C#. En que la sintaxis se ve similar, ¿qué es inferior a la implementación de Java o es un punto de vista religioso?C# vs Java generics
Respuesta
streloksi's link hace un gran trabajo para romper las diferencias. El resumen rápido y sucio es ...
En términos de sintaxis y uso. La sintaxis es más o menos la misma entre los idiomas. Algunas peculiaridades aquí y allá (más notablemente en restricciones). Pero, básicamente, si puedes leer uno, probablemente puedas leer/usar el otro.
La mayor diferencia es en la implementación.
Java utiliza la noción de borrado de tipo para implementar genéricos. En resumen, las clases compiladas subyacentes no son en realidad genéricas. Compilan hasta Objeto y lanzamientos.En efecto, los genéricos de Java son un artefacto de tiempo de compilación y pueden subvertirse fácilmente en tiempo de ejecución.
C# por otro lado, en virtud de la CLR, implementa genéricos hasta el código de bytes. El CLR tomó varios cambios importantes para dar soporte a los genéricos en 2.0. Los beneficios son mejoras en el rendimiento, verificación y reflexión de seguridad de tipo profundo.
De nuevo el proporcionado link tiene una mucho más en profundidad desglose os animo a leer
Leí el enlace de Strelok, la [entrevista] de Anders Hejlsberg (http://www.artima.com/intv/generics2.html) y la [publicación de blog] de Eric Lippert (http://blogs.msdn.com /b/ericlippert/archive/2009/07/30/generics-are-not-templates.aspx). Pero todavía no puedo obtenerlo: ¿cómo C# no hace el borrado de tipo ** y ** los tipos de referencia comparten el mismo código IL? ¿Podrías expandir esto un poco? –
@AlexanderMalakhov todos los tipos de referencia son un tamaño de palabra en el ensamblaje y se pueden manipular con las mismas instrucciones, por lo tanto, pueden compartir el mismo patrón de ensamblaje. ¿Dónde esperarías que difieran? – JaredPar
Supongo que Java hace exactamente lo mismo. Entonces, ¿dónde está la información tipo? ¿Cómo, por ejemplo, la reflexión puede funcionar? –
La diferencia se debe a una decisión de diseño de Microsoft y Sun.
Generics in Java se implementa a través de type erasure por el compilador, lo que significa que la comprobación de tipos se produce en tiempo de compilación, y la información de tipo se elimina. Este enfoque fue tomada para mantener el código heredado compatible con código usando nuevos genéricos:
De Los Tutoriales de Java, Generics: Type Erasure:
Cuando se crea una instancia de un tipo genérico, el compilador traduce esos tipos por una técnica llamada borrado de tipo - un proceso donde el compilador elimina toda la información relacionada con los parámetros de tipo y escribe argumentos dentro de una clase o método . La eliminación de tipos habilita las aplicaciones Java que usan genéricos a mantienen la compatibilidad binaria con Se crearon bibliotecas y aplicaciones Java que antes que los genéricos.
Sin embargo, con generics in C# (.NET), no hay ningún tipo de borrado por el compilador, y los controles de tipo se llevan a cabo durante la ejecución. Esto tiene sus beneficios de que la información de tipo se conserva en el código compilado.
De Wikipedia:
Esta opción de diseño se aprovecha para proporcionan funcionalidades adicionales, tales como permitir la reflexión con preservación de tipos genéricos, así como aliviar algunas de las limitaciones de borrado (tales como incapaz de crear matrices genéricas). Este también significa que no hay rendimiento afectado por los modelos de tiempo de ejecución y conversiones de box normalmente caras.
En lugar de decir ".NET genéricos es mejor que los genéricos de Java", uno debe considerar la diferencia en el enfoque para implementar genéricos. En Java, parece que preservar la compatibilidad era una alta prioridad, mientras que en .NET (cuando se introdujo en la versión 2.0), la obtención de todos los beneficios de usar genéricos era una prioridad más alta.
@Tom ¿Qué significa "Inmunidad del análisis"? – LamonteCristo
Significa que, sí, puede decir "Los genéricos de .NET son mejores que los genéricos de Java". Java debería haber adoptado el enfoque de hacer un cambio radical e implementar correctamente los medicamentos genéricos cuando tenían la oportunidad de hacerlo. – Mike
La "compatibilidad con versiones anteriores" es incorrecta, ambas son compatibles con versiones anteriores. Fue hecho para "Compatibilidad de migración". – kervin
encuentra también this conversación con Anders Hejlsberg que puede ser interesante también. Para resumir los puntos que Anders Hejlsberg hizo con algunas notas adicionales: Se realizaron genéricos de Java para una máxima compatibilidad con JVM que llevó a algunas cosas extrañas en comparación con la aplicación existente que se ven en C#:
Tipo de aplicación fuerzas de borrado para representar cada valor genérico parametrizado como
Object
. Mientras compilador proporciona moldes automáticos entreObject
y el tipo más específico, no eliminar los efectos negativos de los modelos tipo y el boxeo en el rendimiento (por ejemploObject
se convierte al tipo específicoMyClass
oint
tuvo que ser encajonado enInteger
, lo que sería aún más serio para C# /. NET si siguieron el enfoque de borrado de tipo debido a los tipos de valores definidos por el usuario). Como Anders dijo: "usted no recibe ninguna de la eficiencia de la ejecución" (que los genéricos reificadas permiten en C#)Tipo borrado hace que la información disponible en tiempo de compilación en tiempo de ejecución no es accesible. Algo que solía ser
List<Integer>
se convierte simplemente enList
sin posibilidad de recuperar el parámetro de tipo genérico en tiempo de ejecución. Esto dificulta la creación de escenarios de reflexión o generación dinámica de código en torno a los genéricos de Java. Más reciente SO answer muestra una forma de evitarlo a través de clases anónimas. Pero sin trucos, algo como generar código en tiempo de ejecución a través de la reflexión que obtiene elementos de una instancia de colección y lo pone en otra instancia de colección puede fallar en tiempo de ejecución durante la ejecución del código generado dinámicamente: la reflexión no ayuda a detectar desadaptación enList<Double>
en comparación conList<Integer>
en estas situaciones
Pero +1 en la respuesta que enlaza con blog post de Jonathan Pryor.
- 1. System.Reflection vs Generics - performance
- 2. Java generics
- 3. C# Generics
- 4. Java Generics Curiosity
- 5. Java generics pasando parámetros
- 6. Jackson JSON + Java Generics
- 7. Java Generics (comodines)
- 8. Java Generics circulares
- 9. C# Generics y Winform
- 10. C# Generics Instantiation
- 11. Generics/JSON JavaScriptSerializer C#
- 12. C# Generics function
- 13. Java Generics Sintaxis para matrices
- 14. JAXB desmaquillar con java generics
- 15. C# Generics and Type Checking
- 16. C# generics - sin límites inferiores por diseño?
- 17. ¿Cómo se implementan los C# Generics?
- 18. Java Generics comodines Con múltiples clases
- 19. Java Generics tipo conversión de rompecabezas
- 20. java generics y el método addAll
- 21. Java Generics y sumar números juntos
- 22. Uso de Java Generics con Enums
- 23. Limitaciones de Java Generics o uso incorrecto?
- 24. C# vs Java - Listas genéricas
- 25. C++ vs Java en Android
- 26. C# sellado vs Java final
- 27. Java Generics WildCard: <? extiende Número> vs <T extiende Número>
- 28. C# Generics - ¿Cómo devuelvo un tipo específico?
- 29. Generics vs inheritance (cuando no hay clases de colección involucradas)
- 30. Tamaño de caracteres en Java vs. C
parece que esta pregunta ya se ha hecho - http://stackoverflow.com/questions/31693/differences-in-generics#31866 – serg10
Comparación completa [aquí] (http://www.jprl.com/Blog/ archive/development/2007/Aug-31.html), con algunos enlaces. – Strelok