¿Por qué Java se considera más portátil que otros lenguajes como C ++?

16

¿Qué difiere entre "escribir un JRE específico para cada plataforma" para los desarrolladores de Java y "escribir un compilador de C ++ para cada plataforma" para los de C ++?

usuario967316
fuente

Respuestas:

33

Java se compila una vez que se ejecuta en cualquier lugar. C ++ es escribir una vez compilar en cualquier lugar.

Pubby
fuente
3
Bueno, obviamente no has tenido mucha experiencia con el desarrollo de GUI. (Esperando Qt ...)
27
Cualquiera que diga que C ++ es "escribir una vez compilar en cualquier lugar" nunca ha tenido que portar un programa C ++ ...
BlueRaja - Danny Pflughoeft
77
Estoy de acuerdo con BlueRaja. Portar un programa C ++ significa mucho más que portar el compilador. C ++ está más ampliamente presente en entornos críticos donde cosas como el tamaño de un int o la implementación de un sistema de archivos pueden hacer una gran diferencia. Portar NO significa simplemente recompilar.
rahmu
8
@ Pubby8 no, los problemas de portabilidad también provienen de un código bastante estándar que hace suposiciones no portables , como suposiciones sobre la endianidad (lo que te importa, también puedes sufrir en Java), la alineación y el tamaño de los tipos fundamentales.
R. Martinho Fernandes
55
Escribe una vez, depura en todas partes.
bhagyas
25

"escribir un JRE específico para cada plataforma" no es algo que haces cada vez. Portar el JRE a una nueva plataforma es algo que necesita hacer solo una vez. Esta tarea generalmente la realiza el desarrollador / desarrollador principal del programa y / o la plataforma. Muchos factores pueden entrar en juego al decidir quién y cómo se portará el JRE. Entre otras cosas, depende de la licencia con la que se publique (escuché que Java es de código abierto, así que supongo que cualquiera podría hacerlo). Anécdota divertida, Steve Jobs hizo un gran problema al no querer hacerse cargo de la transferencia de Java en Mac , hace aproximadamente un año.

El punto no es cómo o quién porta el JRE, sino el hecho de que una vez que se porta, todas las aplicaciones Java ahora deberían ejecutarse teóricamente fácilmente en la nueva máquina. En ese sentido, el JRE forma una capa de abstracción, ocultando completamente la máquina, lo que permite un fácil portado.

Sin embargo, la realidad no siempre es bonita así. No iré tan lejos como para llamar a la portabilidad un "mito", pero es cierto que no es tan perfecto. Por ejemplo, Java tiene un paquete llamado JNIque permite enviar llamadas nativas, evitando el JRE, evitando así la perfecta portabilidad perfecta, lo que a los fanáticos de Java les gusta llamar "Escribir una vez que se ejecutan en todas partes".

Como se menciona en los comentarios, el enfoque de C ++ para la portabilidad es diferente. Por un lado, es un lenguaje compilado, y esos binarios son casi siempre específicos de la plataforma. Entonces los ejecutables de c ++ nunca serán portables (a diferencia de Java). Por otro lado, portar el compilador a veces puede ser suficiente. La comunidad ha descubierto que al portar el compilador, así como algunas bibliotecas centrales del idioma, los códigos fuente (y no los binarios) podrían ser portátiles.

Sin embargo, C ++ se usa ampliamente en sistemas críticos como compiladores, núcleos, sistemas en tiempo real, sistemas embebidos, ... Hay un aspecto de "bajo nivel" de C ++ que no puede pasarse por alto cuando se habla de portabilidad.

rahmu
fuente
44
La portabilidad no es un mito. La portabilidad perfecta es.
Malcolm
"Aquí es donde Java es muy diferente de C ++, donde cada aplicación es" específica de la máquina "y no se puede portar sin modificar el código". Eso no es cierto, depende de las dependencias. Si solo usa la biblioteca estándar y las bibliotecas con fuentes portables a sus objetivos, codifique una vez y compile en cada destino. Si codifica algo que se puede portar sin modificar el código en C ++, lo único que puede necesitar modificar son los scripts de compilación. Eso ni siquiera es cierto en todos los casos.
Klaim
No olvidemos que C ++ se puede usar como lenguaje de alto nivel y bajo. Se utiliza una gran cantidad de código C ++ en programas en los que un int de 32 bits es muy diferente de un int de 64 bits. El alto nivel siempre será portátil, por supuesto. Pero está lejos de ser una generalización de C ++
rahmu
Creo que puede haber entendido mal lo que digo: puede escribir C ++ correcto con int o cualquier tipo estándar sin molestarse con cosas de bajo nivel. Solo eche un vistazo a las bibliotecas de impulso, la mayoría son solo códigos de alto nivel, y eso es cierto para muchos proyectos de código abierto de C ++. "Puede" ir a un nivel bajo, y si lo hace, también puede evitar cualquier código específico hasta que necesite utilizar una API específica de la plataforma. Pero si no lo necesita, puede escribir C ++ que funcione en todas partes. La dependencia de la plataforma se puede evitar y, a menudo, se encuentra en el código de la biblioteca.
Klaim
Solo para asegurarme de que estoy claro: no digo que todo el código C ++ sea portátil, digo que tal como está, su declaración es incorrecta. Es posible que desee solucionarlo con algo como: "Aquí es donde Java es muy diferente de C ++, donde cada aplicación es" específica de la máquina ", y no se puede portar sin modificar el código o, si el código es realmente portátil y la compilación las secuencias de comandos administran el nuevo objetivo, sin al menos una compilación ".
Klaim
14

No es solo el idioma, son las bibliotecas.

Tanto Java como C ++ proporcionan bibliotecas multiplataforma. Java proporciona un conjunto más rico.

Andy Thomas
fuente
2
Java proporciona un conjunto más rico por defecto. Se pueden encontrar las mismas bibliotecas para C ++, simplemente no forman parte de las bibliotecas estándar y solo tiene que decidir cuáles usar (lo que no es trivial, especialmente si no están instaladas).
Martin York
Comparar las bibliotecas estándar de Java con el universo de bibliotecas para C ++ no es realmente una comparación válida. Java proporciona un conjunto más rico, ya sea que esté comparando las bibliotecas estándar de cada una, o si está comparando el universo de bibliotecas de cada una.
Andy Thomas
3
Definitivamente no estoy de acuerdo con eso. Cualquier cosa en la biblioteca de Java está disponible para C ++ en algunas bibliotecas. Me gusta el hecho de que Java lo tiene todo en un solo lugar, pero decir que es más rico simplemente no es cierto. Tal vez el adjetivo que está buscando está "más integrado"
Martin York
1
+1 volvería a votar de nuevo. Creo que las bibliotecas son el factor más importante en la portabilidad. Si está trabajando en C / C ++ y está haciendo algo que no sea computación pura, habrá bibliotecas (en particular, partes de la biblioteca del sistema) que son radicalmente diferentes entre Windows y Unix, y sutilmente diferentes entre diferentes tipos de Unix. Eso hace que portar sea difícil. Java básicamente no tiene ese problema.
Tom Anderson
1
@Andy Thomas-Cramer: No estoy comparando nada (parece que sí). Estoy diciendo que su declaración es inexacta. Una de las ventajas que tiene Java (y a todos nos encanta por eso) son todas las bibliotecas estándar en un solo lugar. Decir que son más ricos simplemente no es exacto.
Martin York
7

La diferencia es que Java se ejecutará en cualquier plataforma sin recompilar. Tener un compilador de C ++ para cada plataforma no es lo mismo en absoluto.

Highland Mark
fuente
6

Todas las respuestas que comienzan con "La diferencia es ...", o algo muy similar, son básicamente incorrectas (lo siento, pero así es la vida). Realmente hay dos diferencias separadas entre los dos.

Una (que se ha mencionado mucho) es que un programa Java compilado puede (o al menos debería) ejecutarse en cualquier implementación conforme de Java, por lo que incluso después de ser compilado, aún puede mover un programa Java de una plataforma a otra sin volver a compilar . C ++ (al menos normalmente) requiere una nueva compilación para cada plataforma de destino.

El otro es que Java (al menos intenta) asegurar que todo Java escrito correctamente será portátil. Al menos en teoría, no deberías poder escribir ningún código que no sea portátil.

C ++ le permite hacer bastantes cosas que no son portátiles. El estándar C ++ contiene "advertencias" sobre muchas cosas que no son portables (por ejemplo, decirle que obtendrá un comportamiento definido de implementación o un comportamiento indefinido), pero no necesariamente trata de impedir que lo haga en absoluto . Solo por ejemplo, si desea escribir un sistema operativo para hardware que utiliza un bus PCI, es probable que necesite leer / escribir la memoria de configuración PCI. Obviamente, esto no será portátil para sistemas sin un bus PCI, pero si está escribiendo un sistema operativo para hardware con un bus PCI, es bastante necesario. C ++ lo permite, aunque obviamente no será portátil.

Jerry Coffin
fuente
Sin embargo, C ++ no sabe nada sobre el bus PCI ni el hardware.
Nikko
por supuesto que no, esas son cosas específicas de la plataforma que deberán incluirse en bibliotecas específicas de la plataforma. Del mismo modo que Java puede tener bibliotecas específicas de plataforma si es necesario.
Jwenting
1
@ Nikko: No sabe nada al respecto, pero le permite usar lo que sabe al respecto.
Jerry Coffin
@jwenting: la diferencia es que puede escribir las bibliotecas específicas de la plataforma en C ++, pero generalmente no puede escribirlas en Java.
Jerry Coffin
6

Has entendido mal las premisas. Los programas Java son muy portátiles, porque la JVM proporciona un comportamiento estándar garantizado para ser el mismo. Los programas C ++ tienen un entorno menos estandarizado más cercano al hardware real, por lo que el programa debe poder manejar los diversos detalles específicos de la plataforma, como el tamaño de un int, la alineación de palabras, etc., etc.

La JVM en sí no es muy portátil. Es una tarea hercúlea portar una JVM de alto rendimiento a otra plataforma o arquitectura de CPU.


fuente
¡+1 para esa última oración!
rahmu
2

La diferencia es que los programas Java (no es un acrónimo) se pueden distribuir en una forma que se puede ejecutar en cualquier computadora con un JVM instalado, pero C ++ normalmente se distribuye como código fuente, que es muy poco amigable para el usuario o como un grupo de diferentes binarios para diferentes plataformas.

Colin
fuente
¿Eh? Hay compiladores de C ++ que apuntan a la JVM y hay compiladores de Java que apuntan al código nativo. ¿Puede citar la sección específica de la especificación del lenguaje C ++ que dice que los programas C ++ deben distribuirse como código fuente o binarios específicos de la plataforma?
Jörg W Mittag
Allí, edité mi respuesta para usar un lenguaje menos definitivo
Colin
2

Una de las razones por las que Java se considera portátil es que tiene reglas específicas sobre cómo deben valorarse las expresiones aritméticas y prohíbe que las implementaciones las evalúen de otra manera, incluso cuando evaluarlas de manera obligatoria requeriría un código más lento que evaluarlas de manera más precisa Moda.

Por ejemplo, dado

long thing1(int x) {
  return (x+1)-1L;
}
double thing2(int x, float y) {
  return x/y;
}

Los valores de thing1(2147483647)y thing2(1123456700,11234567.0f)deben ser -2147483649L y 99.9999923706054688, respectivamente, aunque los valores aritméticamente correctos serían 2147483647L y 100.0, y aunque en algunas plataformas el código para generar resultados numéricamente incorrectos sería más lento que el código para generar el correcto resultados (en algunas plataformas de 64 bits, forzar el comportamiento de ajuste después de (x + 1) requeriría una instrucción adicional, y en la plataforma 8x87, forzar el valor de 1123456700 a redondear a floatrequeriría una instrucción adicional en comparación con simplemente cargar directamente a un registro de precisión extendida).

Super gato
fuente
1
Por una vez, una nueva respuesta a una vieja pregunta que realmente agrega algo de valor: Java tiene requisitos aritméticos muy precisos y, por supuesto, los tipos de datos primitivos tienen tamaños y semánticas específicos en comparación con C ++. Ninguna otra respuesta a esta fecha menciona esto.
@Snowman: ¿Cómo te gustan los ejemplos particulares elegidos? Personalmente, si estuviese diseñando un lenguaje, no habría hecho que ninguno de los ejemplos devolviera el valor de Java sin el uso de conversiones estrechas (int)para la (x+1)subexpresión del primer ejemplo en el primer ejemplo, para floatel xparámetro del segundo ejemplo , pero obviamente no diseñé el lenguaje .
supercat
Creo que tienen sentido. Lo importante para cualquier lenguaje es tener una semántica bien definida. Independientemente de si uno está de acuerdo con una decisión de diseño de lenguaje dada, lo importante es poder mirar el código y saber cómo funciona. Java generalmente hace eso, con pocos casos de comportamiento indefinido.
1

La cantidad de trabajo para las herramientas de soporte es de hecho similar, la diferencia radica en otra parte. Una vez que se ha compilado un programa C ++ para una plataforma, debe compilarlo nuevamente si desea usarlo en una plataforma diferente. Sin embargo, cuando se compila un programa Java, puede moverlo a cualquier otra plataforma con un entorno de tiempo de ejecución sin tener que volver a compilarlo.


fuente
1

Respondiendo el título "¿Es la portabilidad un mito?", En lugar de "¿Cuál es mejor en portabilidad, Java o C ++", diré que la portabilidad parcial es posible, pero la portabilidad total es un mito.

Algo que insisto en escribir, y se aplica a esta pregunta, es que los desarrolladores ya no están trabajando solo con lenguajes de programación, sino con marcos de programación completos.

Y esos marcos, incluyen bibliotecas, bases de datos, interfaces gráficas.

¿Qué lenguaje de programación o qué marco de programación es más portátil?

Bueno, depende de cuál sea tu aplicación. está tratando de lograrlo.

umlcat
fuente
1

La cosa es que "usted" no escribe el JRE, escribe el código Java que se ejecuta en cualquier JRE. "Usted" no escribir el código C ++, que puede requerir cambios por usted antes de que se compilará en otra plataforma.

James Anderson
fuente
0

Muchas personas olvidan o no tienen en cuenta la realidad de Java cuando dicen que "es 100% portátil" o frases como esa.

Casi todas las principales corporaciones / software tenían al menos 1 implementación casera de Java con un JRE asociado en el pasado reciente y algunas aún lo mantienen, Microsoft, IBM y Apple, por ejemplo, tenían su propia versión de Java que reflejaba su propias ideas y pensamientos sobre dónde debe ir la industria y ese lenguaje.

¿Cómo es eso de "portátil"? Un JRE donde sea que vayas.

Y esto sin tener en cuenta lo que Sun / Oracle estaba haciendo.

Un ejemplo de por qué el código Java no está realmente lejos de C y C ++ en términos de portabilidad son las GUI y los servidores gráficos, Apple tuvo una implementación no estándar del marco GUI para su propio JRE, como consecuencia hubo muchas dolores de cabeza y doble trabajo para cualquiera que quisiera crear / portar una GUI usando Java para máquinas Apple y se vieron obligados a lidiar con Quartz (¿cómo es eso en términos de "apalancamiento" y lenguajes de alto nivel?).

A veces, incluso las palabras más utilizadas no reflejan realmente el significado que las personas suelen darles, para mí el término "portabilidad" en el mundo de Java es más como "perspectiva" en el sentido común; En términos comerciales y financieros, hay una mejor perspectiva para usted si adopta Java en lugar de otros idiomas (al menos en el momento en que nació Java) porque ya tiene mucho trabajo hecho por un lado (obtiene un JRE en cualquier cosa eso puede considerarse una "computadora") y es probable que su base de código sea portátil, ya que necesita menos recursos para portar su programa, eso es todo, ya sea que dicho recurso sea dinero, tiempo o mano de obra no importa, es menor umbral en comparación con otras tecnologías y para eso es Java, está bajando ese umbral.

Por supuesto, esto es cierto si acepta las premisas de Java, lo que significa una máquina virtual con recolección de basura, lo que significa que consume más recursos en comparación con los idiomas nativos, si realmente desea exprimir al máximo su CPU o granja de servidores I no piense que puede adoptar Java a menos que tenga muy pocos recursos o que su empresa sea realmente pequeña.

Todavía tengo que encontrar una sola aplicación Java no trivial que contenga solo 1 versión para cada línea de código o funcionalidad (es decir, sin ninguna materia específica de la plataforma) y es 100% portátil entre todos los JRE principales.

usuario2485710
fuente