Articulo de referencia

Críticas a Java

El lenguaje de programación Java y la plataforma de software Java han sido criticados por decisiones de diseño que incluyen la implementación de genéricos, la programación orien...

El lenguaje de programación Java y la plataforma de software Java han sido criticados por decisiones de diseño que incluyen la implementación de genéricos, la programación orientada a objetos forzada, el manejo de números sin signo, la implementación de aritmética de punto flotante y un historial de vulnerabilidades de seguridad en la implementación principal de la máquina virtual Java, HotSpot . El software escrito en Java, especialmente sus primeras versiones, ha sido criticado por su rendimiento en comparación con el software escrito en otros lenguajes de programación. Los desarrolladores también han señalado que las diferencias entre las diversas implementaciones de Java deben tenerse en cuenta al escribir programas Java complejos que deban funcionar con todas ellas. [ 1 ]

Sintaxis y semántica del lenguaje

Excepciones comprobadas

Java introdujo las excepciones verificadas, donde un método debe declarar las excepciones verificadas que lanza en su firma. Esto puede generar código repetitivo innecesariamente extenso . Ningún lenguaje importante ha seguido el ejemplo de Java en la implementación de excepciones verificadas.

Medicamentos genéricos

Cuando se añadieron los genéricos a Java 5.0, ya existía un amplio marco de clases (muchas de las cuales ya estaban obsoletas ), por lo que los genéricos se implementaron utilizando el borrado de tipos para permitir la compatibilidad de migración y la reutilización de estas clases existentes. Esto limitó las características que se podían proporcionar, en comparación con otros lenguajes. [ 2 ] [ 3 ]

Debido a que los genéricos se implementan mediante borrado de tipos, el tipo real de un parámetro de plantilla E no está disponible en tiempo de ejecución. Por lo tanto, las siguientes operaciones no son posibles en Java: [ 4 ]

public class MyClass < E > { public static void myMethod ( Object item ) { if ( item instanceof E ) { // Error de compilación // ... } E item2 = new E (); // Error de compilación E [] iArray = new E [ 10 ] ; // Error de compilación } }

Además, en 2016 se encontró el siguiente ejemplo que revelaba que Java era inestable y, a su vez, hacía que las JVM que generaban ClassCastExceptions o cualquier otro tipo de error en tiempo de ejecución fueran técnicamente no conformes. [ 5 ] Esto se corrigió en Java 10.

clase Nullless < T , U > { clase Constrain < B extends U > { // algo aquí } final Constrain <? super T > constrain ; final U u ;Sin valores nulos ( T t ) { u = coerce ( t ); constrain = getConstrain (); }< B extiende U > U upcast ( Constrain < B > constrain , B b ) { return b ; }U coerce ( T t ) { return upcast ( constrain , t ); }Constrain <? super T > getConstrain () { return constrain ; }public static void main ( String [] args ) { String zero = new Nullless < Integer , String > ( 0 ). u ; } }

Orientación al sustantivo

Por diseño, Java anima a los programadores a pensar en una solución en términos de sustantivos (clases) que interactúan entre sí, y a pensar en verbos (métodos) como operaciones que pueden realizarse sobre o por ese sustantivo. [ 6 ] Steve Yegge argumenta que esto causa una restricción innecesaria a la expresividad del lenguaje porque una clase puede tener múltiples funciones que operan sobre ella, pero una función está ligada a una clase y nunca puede operar sobre múltiples tipos. [ 7 ]

Muchos otros lenguajes multiparadigma admiten funciones como una construcción de nivel superior. Al combinarse con otras características como la sobrecarga de funciones (un verbo, varios sustantivos) y las funciones genéricas (un verbo, una familia de sustantivos con ciertas propiedades), el programador puede decidir si resolver un problema específico en términos de sustantivos o verbos. Java versión 8 introdujo algunas características de programación funcional.

Tipos de enteros sin signo

Java carece de tipos de enteros sin signo nativos . Los datos sin signo se generan a menudo a partir de programas escritos en C , y la falta de estos tipos impide el intercambio directo de datos entre C y Java. Los números grandes sin signo también se utilizan en varios campos del procesamiento numérico, incluida la criptografía, lo que puede hacer que Java sea más inconveniente para estas tareas. [ 8 ] Aunque es posible sortear este problema utilizando código de conversión y tipos de datos más grandes, hace que usar Java sea engorroso para manejar datos sin signo. Si bien un entero con signo de 32 bits puede usarse para almacenar un valor sin signo de 16 bits sin pérdida, y un entero con signo de 64 bits un entero sin signo de 32 bits, no existe un tipo más grande para almacenar un entero sin signo de 64 bits. En todos los casos, la memoria consumida puede duplicarse, y normalmente cualquier lógica que dependa del desbordamiento del complemento a dos debe reescribirse. Si se abstrae, las llamadas a funciones se vuelven necesarias para muchas operaciones que son nativas de algunos otros lenguajes. Alternativamente, es posible usar enteros con signo de Java para emular enteros sin signo del mismo tamaño, pero esto requiere un conocimiento detallado de las operaciones bit a bit . [ 9 ] Se proporcionó cierto soporte para tipos de enteros sin signo en JDK 8, pero no para bytes sin signo y sin soporte en el lenguaje Java. [ 10 ]

Sobrecarga del operador

Java ha sido criticado por no admitir operadores definidos por el usuario. La sobrecarga de operadores mejora la legibilidad, [ 11 ] por lo que su ausencia puede hacer que el código Java sea menos legible, especialmente para clases que representan objetos matemáticos, como números complejos y matrices. Java solo tiene un uso no numérico de un operador: para la concatenación de cadenas. Sin embargo, esto lo implementa el compilador, que genera código para crear instancias. Es imposible crear sobrecargas de operadores definidas por el usuario.++=StringBuilder

Tipos de valores compuestos

Java carece de tipos de valor compuestos, como las estructuras en C, conjuntos de datos que se manipulan directamente en lugar de indirectamente a través de referencias. Los tipos de valor a veces pueden ser más rápidos y pequeños que las clases con referencias. [ 12 ] [ 13 ] [ 14 ] Por ejemplo, el de Java HashMapse implementa como una matriz de referencias a HashMap.Entryobjetos, [ 15 ] que a su vez contienen referencias a objetos clave y valor. Buscar algo requiere una doble desreferenciación ineficiente. Si Entryfuera un tipo de valor, la matriz podría almacenar pares clave-valor directamente, eliminando la primera indirección, aumentando la localidad de referencia y reduciendo el uso de memoria y la fragmentación del montón . Además, si Java admitiera tipos primitivos genéricos, las claves y los valores podrían almacenarse en la matriz directamente, eliminando ambos niveles de indirección.

Grandes matrices

Java ha sido criticado por no admitir arreglos de 2³¹ (aproximadamente 2100 millones) o más elementos. [ 16 ] [ 17 ] Esta es una limitación del lenguaje; la Especificación del Lenguaje Java , Sección 10.4, establece que:

Los arreglos deben indexarse ​​mediante valores enteros... Intentar acceder a un componente de un arreglo con un índice largo produce un error de compilación. [ 18 ]

La compatibilidad con grandes matrices también requeriría cambios en la JVM. [ 19 ] Esta limitación se manifiesta en áreas como las colecciones, que están limitadas a 2 mil millones de elementos [ 20 ] , y la incapacidad de mapear en memoria segmentos de archivos continuos mayores de 2  GB. [ 21 ] Java también carece (aparte de sus matrices 2D) de matrices multidimensionales (bloques de memoria únicos asignados contiguamente y a los que se accede mediante una sola indirección), lo que limita el rendimiento para la computación científica y técnica. [ 13 ]

Integración de primitivas y matrices

Los arreglos y los tipos primitivos son algo especiales y deben tratarse de manera diferente a las clases. Esto ha sido criticado [ 22 ] porque requiere muchas variantes de funciones al crear bibliotecas de propósito general.

Paralelismo

Per Brinch Hansen argumentó en 1999 [ 23 ] que la implementación del paralelismo en Java, en general, y los monitores en particular, no proporcionan las garantías y los mecanismos de control necesarios para una programación paralela segura y confiable. Si bien un programador puede establecer convenciones de diseño y codificación , el compilador no puede hacer ningún intento por aplicarlas, por lo que el programador puede escribir, sin darse cuenta, código inseguro o poco confiable.

Publicación por entregas

Java proporciona un mecanismo para la serialización de objetos , donde un objeto puede representarse como una secuencia de bytes que incluye sus campos de datos, junto con información de tipo sobre sí mismo y sus campos. Después de serializar un objeto, este puede deserializarse; es decir, la información de tipo y los bytes que representan sus datos pueden usarse para recrear el objeto en memoria. [ 24 ] Esto plantea riesgos de seguridad teóricos y reales muy serios. [ 25 ] [ 26 ]

Aritmética de punto flotante

Aunque la aritmética de punto flotante de Java se basa en gran medida en IEEE 754 ( Estándar para la aritmética binaria de punto flotante ), algunas características estándar obligatorias no son compatibles incluso cuando se utiliza el modificador (ahora redundante [ 27 ] ) strictfp, como los indicadores de excepción y el redondeo dirigido. Los tipos de precisión extendida definidos por IEEE 754 (y compatibles con muchos procesadores) no son compatibles con Java. [ 28 ] [ 29 ] [ 30 ]

Falta de tuplas

Java no admite tuplas de forma nativa , lo que da lugar a una proliferación de implementaciones de terceros que deben ser importadas y gestionadas por el programador. [ 31 ] El argumento en contra de una clase de tupla genérica es el peligro que supone al proliferar código difícil de mantener. [ 32 ]

Relación abstracta entre código y hardware

En 2008, el Centro de Soporte de Tecnología de Software del Departamento de Defensa de los Estados Unidos publicó un artículo en el Journal of Defense Software Engineering que analizaba la inadecuación de Java como primer lenguaje de programación. Entre las desventajas se mencionaba que los estudiantes "no comprendían la relación entre el programa fuente y el funcionamiento real del hardware" y la imposibilidad de "desarrollar una comprensión del coste computacional de lo escrito, ya que es extremadamente difícil saber qué ejecutará finalmente cualquier llamada a un método". [ 33 ] En 2005, Joel Spolsky criticó Java por ser una parte excesivamente centrada en los planes de estudio universitarios en su ensayo The Perils of JavaSchools . [ 34 ] Otros, como Ned Batchelder, discrepan con Spolsky por criticar las partes del lenguaje que le resultaban difíciles de entender, afirmando que el comentario de Spolsky era más bien una "discurso subjetivo". [ 35 ]

Actuación

Antes del año 2000, cuando se implementó la máquina virtual HotSpot en Java 1.3, hubo muchas críticas sobre su rendimiento. Se ha demostrado que Java se ejecuta a una velocidad comparable a la del código nativo optimizado, y las implementaciones modernas de la JVM se comparan regularmente con las plataformas de lenguaje más rápidas disponibles , generalmente no más de tres veces más lentas que C y C++. [ 36 ]

El rendimiento ha mejorado sustancialmente desde las primeras versiones. [ 37 ] Se ha demostrado que el rendimiento de los compiladores JIT en relación con los compiladores nativos es bastante similar en algunas pruebas optimizadas. [ 37 ] [ 38 ] [ 39 ]

El código de bytes de Java puede interpretarse en tiempo de ejecución mediante una máquina virtual o compilarse en tiempo de carga o ejecución para convertirse en código nativo que se ejecuta directamente en el hardware del ordenador. La interpretación es más lenta que la ejecución nativa, pero la compilación en tiempo de carga o ejecución conlleva una penalización inicial en el rendimiento. Las implementaciones modernas de la JVM utilizan el método de compilación, por lo que, tras el tiempo de arranque inicial, el rendimiento es similar al del código nativo.

El diseñador y programador de videojuegos John Carmack concluyó en 2005 sobre Java en teléfonos móviles : «El mayor problema es que Java es realmente lento. A nivel de CPU, memoria, pantalla y comunicaciones, la mayoría de los teléfonos móviles modernos deberían ser plataformas de juego considerablemente mejores que una Game Boy Advance. Con Java, en la mayoría de los teléfonos te quedas con una potencia de CPU similar a la de un IBM PC original de 4,77 MHz (sic) , y un control pésimo sobre todo». [ 40 ]

Seguridad

La plataforma Java proporciona una arquitectura de seguridad [ 41 ] diseñada para permitir al usuario ejecutar código de bytes no confiable en un entorno aislado (sandbox) para protegerse contra software malicioso o mal escrito. Esta función de aislamiento tiene como objetivo proteger al usuario restringiendo el acceso a las funciones y API de la plataforma que podrían ser explotadas por malware , como el acceso al sistema de archivos local o a la red, o la ejecución de comandos arbitrarios.

En 2010, se produjo un aumento significativo del software malicioso que aprovechaba las vulnerabilidades de seguridad en los mecanismos de aislamiento (sandboxing) utilizados por las implementaciones de Java, incluida la de Oracle. Estas vulnerabilidades permitían que código no confiable eludiera las restricciones del aislamiento, exponiendo al usuario a ataques. Si bien las actualizaciones de seguridad corrigieron las vulnerabilidades, estas seguían siendo explotadas en máquinas sin dichas actualizaciones. [ 42 ]

Los críticos han sugerido que los usuarios no actualizan sus instalaciones de Java porque desconocen que las tienen o cómo actualizarlas. Muchas organizaciones restringen la instalación de software por parte de los usuarios, pero tardan en implementar las actualizaciones. [ 42 ] [ 43 ]

Oracle ha sido criticada por no proporcionar actualizaciones con prontitud para vulnerabilidades de seguridad conocidas. [ 44 ] Cuando Oracle finalmente lanzó un parche para vulnerabilidades ampliamente explotadas en Java 7, eliminó Java 6 de las máquinas de los usuarios, a pesar de que era ampliamente utilizado por aplicaciones empresariales que Oracle había declarado que no se veían afectadas por dichas vulnerabilidades. [ 45 ]

En 2007, un equipo de investigación liderado por Marco Pistoia expuso otra importante falla del modelo de seguridad de Java, [ 46 ] basada en la inspección de la pila . Cuando se accede a un recurso sensible a la seguridad, el administrador de seguridad activa un código que recorre la pila de llamadas para verificar que el código fuente de cada método tenga autoridad para acceder al recurso. Esto se hace para prevenir ataques de agente confundido , que ocurren cada vez que un programa legítimo y con más privilegios es engañado por otro para que haga un mal uso de su autoridad. El problema del agente confundido es un tipo específico de escalada de privilegios . Pistoia observó que cuando se accede a un recurso sensible a la seguridad, el código responsable de adquirir el recurso puede que ya no esté en la pila. Por ejemplo, un método ejecutado en el pasado puede haber modificado el valor de un campo de objeto que determina qué recurso usar. Esa llamada al método puede que ya no esté en la pila cuando se inspecciona.

Algunos permisos son implícitamente equivalentes a los de Java AllPermission. Estos incluyen el permiso para cambiar el administrador de seguridad actual (y reemplazarlo por uno que potencialmente podría eludir la inspección de la pila), el permiso para instanciar y usar un cargador de clases personalizado (que podría asociarse AllPermissiona una clase maliciosa al cargarlo) y el permiso para crear un permiso personalizado (que podría declararse tan poderoso como a AllPermissiontravés de su impliesmétodo). Estos problemas están documentados en los dos libros de Pistoia sobre seguridad en Java. [ 47 ] [ 48 ]

Instalaciones paralelas

Antes de Java 7, los instaladores no eliminaban las instalaciones antiguas de Java. Era común encontrar varias instalaciones de Java en un mismo equipo Windows. [ 49 ] [ 50 ] [ 51 ] Se permitían las instalaciones múltiples, las cuales podían ser utilizadas por programas que dependían de versiones específicas, incluyendo programas maliciosos. Este problema se solucionó en Java 7: con el permiso del usuario, el instalador elimina las instalaciones anteriores. [ 52 ]

La compilación JIT utiliza fundamentalmente datos ejecutables y, por lo tanto, plantea desafíos de seguridad y posibles vulnerabilidades.

Véase también

Notas

  1. Wong, William (27 de mayo de 2002). "Escribe una vez, depura en todas partes" . electronicdesign.com. Archivado del original el 21 de marzo de 2009. Recuperado el 3 de agosto de 2008. Hasta ahora, la promesa de Java de "escribe una vez, ejecuta en todas partes" no se ha cumplido. La mayor parte de una aplicación Java migrará entre la mayoría de las implementaciones de Java, pero aprovechar una característica específica de la máquina virtual causa problemas de portabilidad.
  2. "Genéricos en Java" . Object Computing, Inc. Archivado del original el 2 de enero de 2007. Consultado el 9 de diciembre de 2006 .
  3. "¿Qué falla en Java?: Borrado de tipos" . 6 de diciembre de 2006. Archivado del original el 22 de julio de 2012. Consultado el 9 de diciembre de 2006 .
  4. "Borrado de tipo" .
  5. Amin, Nada; Tate, Ross (19 de octubre de 2016). "Los sistemas de tipos de Java y Scala son inestables: la crisis existencial de los punteros nulos" . ACM SIGPLAN Notices . 51 (10): 838–848 . doi : 10.1145/3022671.2984004 . ISSN 0362-1340 . 
  6. "Especificaciones de Java SE" .
  7. Yegge, Steve. "Ejecución en el reino de los sustantivos" .
  8. "Las bibliotecas de Java deberían ofrecer soporte para la aritmética de enteros sin signo" . Base de datos de errores, Sun Developer Network . Oracle . Consultado el 18 de enero de 2011 .
  9. Owen, Sean R. (5 de noviembre de 2009). "Java y unsigned int, unsigned short, unsigned byte, unsigned long, etc. (O más bien, la falta de ellos)" . Recuperado el 9 de octubre de 2010 .
  10. "API de aritmética de enteros sin signo ahora en JDK 8 (blog de Oracle de Joseph D. Darcy)" . Consultado el 15 de mayo de 2016 .
  11. "Sobrecarga de operadores en C++" . 7 de abril de 2016. Archivado del original el 5 de febrero de 2020. Consultado el 5 de febrero de 2020 .
  12. Panel del Foro Java Grande (noviembre de 1998). "Informe del Foro Java Grande: Cómo hacer que Java funcione para la computación de alto rendimiento" (PDF) . SC98 . Archivado del original (PDF) el 18 de mayo de 2013. Recuperado el 10 de febrero de 2012 .
  13. 1 2 Moreira, JE; SP Midkiff; M. Gupta; PV Artigas; M. Snir; RD Lawrence (2000). "Programación Java para computación numérica de alto rendimiento". IBM Systems Journal . 39 (1): 21– 56. CiteSeerX 10.1.1.13.1554 . doi : 10.1147/sj.391.0021 . Los arreglos multidimensionales rectangulares verdaderos son las estructuras de datos más importantes para la computación científica y de ingeniería. 
  14. Hutchinson, Ben (14 de junio de 2008). "La JVM necesita tipos de valor" . Recuperado el 3 de febrero de 2012 .
  15. "java.util.HashMap Código fuente" . JDK 8. zGrepCode . Consultado el 6 de agosto de 2018 .
  16. Arndt, Holger; Bundschus, Markus; Naegele, Andreas (2009). "Hacia una biblioteca de matrices de próxima generación para Java" (PDF) . 33.ª Conferencia Anual Internacional IEEE sobre Software y Aplicaciones Informáticas, 2009. pp. 460–467 . CiteSeerX 10.1.1.471.7567 . doi : 10.1109/compsac.2009.67 . ISBN   978-0-7695-3726-9. S2CID 14672978 . ...en Java no es posible tener arreglos con más de 2 31 entradas... 
  17. "¿Por qué la función Collection.size() de Java devuelve un entero?" . Stack Overflow . Archivado del original el 26 de marzo de 2013 . Consultado el 10 de febrero de 2012 .
  18. James Gosling; Bill Joy; Guy Steele; Gilad Bracha. "La especificación del lenguaje Java" (Tercera edición). Addison Wesley . Consultado el 6 de febrero de 2012 . 
  19. Lowden, James (24 de marzo de 2009). "Propuesta: Grandes matrices (segunda toma)" . Lista de correo de Java.net coin-dev . Recuperado el 10 de febrero de 2012 .
  20. "java.util.Collection" . Especificación de la API de la plataforma Java™, edición estándar 7. Consultado el 10 de febrero de 2012 .
  21. "java.nio.ByteBuffer" . Especificación de la API de la plataforma Java™, edición estándar 7. Consultado el 6 de febrero de 2012 .
  22. Sherman R. Alpert (IBM) (1998). "Los tipos primitivos se consideran perjudiciales" . Java Report, noviembre de 1998 (volumen 3, número 11) . Consultado el 18 de noviembre de 2015 .
  23. Brinch Hansen (abril de 1999). "El paralelismo inseguro de Java" (PDF) . SIGPLAN . Consultado el 13 de octubre de 2012 .URL alternativa
  24. Serialización y deserialización en Java con ejemplo (por el sitio web geeksforgeeks)
  25. La serialización debe morir. Problemas de seguridad y dificultades con la serialización de objetos aleatorios. Por dzone.com
  26. Bloch, Joshua (2018). Java eficaz . Addison-Wesley. págs. 339–345 . ISBN  978-0-13-468599-1.
  27. "JEP 306: Restaurar la semántica de punto flotante siempre estricta" .
  28. Kahan, W.; Joseph D. Darcy (1 de marzo de 1998). "Cómo el punto flotante de Java perjudica a todos en todas partes" (PDF) . Recuperado el 9 de diciembre de 2006 .
  29. "Tipos, valores y variables" . Sun Microsystems . Consultado el 9 de diciembre de 2006 .
  30. "Teoría y práctica de Java: ¿Cuál es el punto? Trucos y trampas con números de coma flotante y decimales" . IBM. 1 de enero de 2003. Consultado el 19 de noviembre de 2011 .
  31. "Qué falla en Java 8, Parte V: Tuplas – DZone" . dzone.com . Consultado el 18 de marzo de 2023 .
  32. ^ Bourrillion, Kevin (31 de marzo de 2010). "Java.util.Par" .
  33. Robert BK Dewar; Edmond Schonberg (1 de enero de 2008). "Educación en Ciencias de la Computación: ¿Dónde están los ingenieros de software del mañana?" . CrossTalk enero de 2008 . Centro de Soporte de Tecnología de Software del Departamento de Defensa de EE. UU . Archivado del original el 12 de abril de 2009 . Recuperado el 15 de marzo de 2015 . Los escollos de Java como primer lenguaje de programación [...] A los estudiantes les resultaba difícil escribir programas que no tuvieran una interfaz gráfica, no tenían idea de la relación entre el programa fuente y lo que el hardware haría realmente, y (lo más perjudicial) no entendían en absoluto la semántica de los punteros, lo que hacía que el uso de C en la programación de sistemas fuera muy desafiante.
  34. Joel Spolsky (29 de diciembre de 2005). "Joel on Software – Los peligros de las escuelas de Java" . joelonsoftware . Consultado el 18 de noviembre de 2015. Ya es bastante malo que las escuelas de Java no logren descartar a los jóvenes que nunca serán grandes programadores, algo que las escuelas podrían justificadamente decir que no es su problema. La industria, o al menos los reclutadores que usan grep, seguramente claman por que se enseñe Java. Pero las escuelas de Java tampoco logran entrenar las mentes de los jóvenes para que sean lo suficientemente hábiles, ágiles y flexibles como para realizar un buen diseño de software.
  35. Ned Batchelder (1 de enero de 2006). "Joel Spolsky es un viejo cascarrabias" . nedbatchelder.com . Recuperado el 2 de febrero de 2016. ¿Por qué Joel elige los punteros y la recursión como los dos conceptos clave? ¿Porque los encontró difíciles? Como señala Tim Bray, Java es perfectamente competente en recursión, y la concurrencia puede ser un concepto más importante y difícil de dominar en cualquier caso. El énfasis en la recursión en los lenguajes Lisp es un poco exagerado y no se traslada a otras culturas de programación. ¿Por qué la gente piensa que es tan importante para la ingeniería de software? No me malinterpreten: me encanta la recursión cuando es la herramienta adecuada para el trabajo, pero eso no es tan frecuente como para justificar el enfoque de Joel en ella como un concepto fundamental. Mientras buscamos conceptos difíciles que separan a los hombres de los niños, ¿qué hay del que nos hizo pelear a Joel y a mí hace dos años: las excepciones? Básicamente, no le gustan porque lo confunden. ¿Acaso es diferente a que a un programador de Java no le gusten los punteros? Sí, se pueden evitar las excepciones y usar valores de retorno de estado, pero también se puede intentar evitar los punteros a toda costa. ¿Significa eso que se debe hacer? Así que Joel domina los conceptos que le gustan (punteros y recursión) y lamenta su declive, pero parece no darse cuenta de que existen conceptos más recientes que nunca ha comprendido, mientras que los jóvenes programadores de Java se sienten como en casa.
  36. "Juego de evaluación comparativa de lenguajes informáticos: Java vs Gnu C++" . benchmarksgame.alioth.debian.org. Archivado del original el 13 de enero de 2015. Consultado el 19 de noviembre de 2011 .
  37. 1 2 J.P.Lewis y Ulrich Neumann. "Rendimiento de Java frente a C++" . Laboratorio de Tecnología Gráfica e Inmersiva, Universidad del Sur de California .
  38. "The Java Faster than C++ Benchmark" . Consultado el 15 de mayo de 2016 .
  39. FreeTTS – Un estudio de caso de rendimiento Archivado el 25 de marzo de 2009 en Wayback Machine , Willie Walker, Paul Lamere, Philip Kwok
  40. John D. Carmack (27 de marzo de 2005). "Aventuras con el teléfono móvil" . Blog de John Carmack . armadilloaerospace.com. Archivado del original el 24 de noviembre de 2015. Consultado el 10 de noviembre de 2015 .
  41. Arquitectura de seguridad de la plataforma Java SE . Oracle. Consultado el 23 de abril de 2013.
  42. 1 2 "Investigadores destacan el reciente aumento de las vulnerabilidades de seguridad en Java" .
  43. "¿Has comprobado Java?" . Archivado del original el 21 de septiembre de 2012 . Consultado el 25 de noviembre de 2010 .
  44. "Oracle conocía fallos críticos de Java desde abril" . The Register . 30 de agosto de 2012. Consultado el 30 de agosto de 2012 .
  45. "La actualización de seguridad de Java, "silenciosa pero letal", daña las aplicaciones heredadas – dev" . The Register . Consultado el 15 de mayo de 2016 .
  46. Pistoia, Marco; Banerjee, Anindya; Naumann, David A. (mayo de 2007). «Más allá de la inspección de pila: un modelo unificado de control de acceso y seguridad del flujo de información». Simposio IEEE de 2007 sobre seguridad y privacidad (SP '07) . IEEE. págs. 149-163 . doi : 10.1109/sp.2007.10 . ISBN  978-0-7695-2848-9. S2CID 4112294 . 
  47. Pistoia, Marco, ed. (1999). Java 2 network security . ITSO networking series (2.ª ed.). Upper Saddle River, Nueva Jersey: Prentice Hall. ISBN  978-0-13-015592-4.
  48. Pistoia, Marco, ed. (2004). Enterprise Java security: building secure J2EE applications . Boston, Mass. Munich: Addison-Wesley. ISBN 978-0-321-11889-9.
  49. Grimes, Roger A. (15 de noviembre de 2011). "Las versiones antiguas de Java generan nuevas vulnerabilidades de seguridad" . InfoWorld . Recuperado el 10 de septiembre de 2023 .
  50. Krill, Paul (4 de mayo de 2012). "Oracle insta a eliminar las versiones antiguas de Java debido a riesgos de seguridad" . InfoWorld . Consultado el 10 de septiembre de 2023 .
  51. "¿Por qué debería desinstalar versiones anteriores de Java de mi sistema?" . Java . 10 de septiembre de 2023 . Consultado el 10 de septiembre de 2023 .
  52. "Actualización automática de Java 6 a Java 7" . Oracle . 10 de septiembre de 2023. Consultado el 10 de septiembre de 2023 .
  • Libre pero encadenado: la trampa de Java , un ensayo de Richard Stallman, del movimiento del software libre (fechado el 12 de abril de 2004).
  • Formación en Ciencias de la Computación: ¿Dónde están los ingenieros de software del futuro? (8 de enero de 2008)
  • ¿Cuáles son las características negativas de Java?