Por que o Java é considerado mais portátil que outras linguagens como C ++?

16

O que difere entre "escrever um JRE específico para cada plataforma" para desenvolvedores Java e "escrever um compilador C ++ para cada plataforma" para C ++?

user967316
fonte

Respostas:

33

Java é compilado uma vez executado em qualquer lugar. C ++ é escrever uma vez compilar em qualquer lugar.

Pubby
fonte
3
Bem, obviamente você não teve muita experiência com o desenvolvimento de GUI. (Aguardando Qt ...)
27
Qualquer um que afirma que C ++ é "escrever uma vez em qualquer lugar de compilação" nunca teve a porta de um programa C ++ ...
BlueRaja - Danny Pflughoeft
7
Eu concordo com o BlueRaja. Portar um programa C ++ significa muito mais do que portar o compilador. O C ++ está mais amplamente presente em ambientes críticos, onde coisas como o tamanho de um int ou a implementação de um sistema de arquivos podem fazer uma diferença tão grande. Portar NÃO significa simplesmente recompilar.
rahmu 27/09/11
8
@ Pubby8 não, os problemas de portabilidade também vêm de códigos bastante padrão que fazem suposições não portáveis , como suposições sobre endianness (lembre-se, você também pode sofrer em Java), alinhamento e tamanho de tipos fundamentais.
R. Martinho Fernandes
5
Escreva uma vez, depure em todos os lugares.
bhagyas
25

"escrever um JRE específico para cada plataforma" não é algo que você faz sempre. Portar o JRE para uma nova plataforma é algo que você precisa fazer apenas uma vez. Essa tarefa geralmente é realizada pelos mantenedores / desenvolvedores principais do programa e / ou da plataforma. Muitos fatores podem entrar em jogo ao decidir quem e como o JRE seria portado. Entre outras coisas, depende do licenciado sob o qual foi publicado (ouvi dizer que Java é Open Source, então acho que alguém poderia fazê-lo). Anedota engraçada, Steve Jobs fez muita coisa por não querer cuidar da portabilidade do Java no Mac , cerca de um ano atrás.

O ponto não é como ou quem move o JRE, mas o fato de que, uma vez portado, todo aplicativo Java agora deve, teoricamente, ser executado facilmente na nova máquina. Nesse sentido, o JRE forma uma camada de abstração, ocultando completamente a máquina, permitindo fácil portabilidade.

No entanto, a realidade nem sempre é bonita assim. Não vou ao ponto de chamar a portabilidade um "mito", mas é verdade que não é tão perfeito. Por exemplo, o Java possui um pacote chamado JNIque permite o envio de chamadas nativas, ignorando o JRE, impedindo a perfeita portabilidade perfeita, o que os fãs de Java gostam de chamar de "Escrever uma vez executado em qualquer lugar".

Como mencionado nos comentários, a abordagem do C ++ para portabilidade é diferente. Por um lado, é uma linguagem compilada e esses binários são quase sempre específicos da plataforma. Portanto, os executáveis ​​do c ++ nunca serão portáveis ​​(ao contrário do Java). Por outro lado, portar o compilador às vezes pode ser suficiente. A comunidade descobriu que, ao transportar o compilador e algumas bibliotecas principais do idioma, os códigos-fonte (e não os binários) podem ser portáveis.

No entanto, o C ++ é amplamente utilizado em sistemas críticos como compiladores, kernels, sistemas em tempo real, sistemas embarcados, ... Há um aspecto de "nível baixo" do C ++ que não pode ser esquecido quando se fala em portabilidade.

rahmu
fonte
4
Portabilidade não é um mito. Portabilidade perfeita é.
Malcolm
"é aqui que o Java é muito diferente do C ++, onde cada aplicativo é" específico da máquina "e não pode ser portado sem modificar o código." Isso não é verdade, depende das dependências. Se você usar apenas a biblioteca e bibliotecas padrão com fontes portáteis para seus destinos, codifique uma vez e compile em cada destino. Se você codificar algo que pode ser portado sem modificar o código em C ++, a única coisa que pode ser necessário modificar são os scripts de construção. Isso nem é verdade em todos os casos.
precisa saber é o seguinte
Não devemos esquecer que o C ++ pode ser usado como uma linguagem de alto e baixo nível. Muito código C ++ é usado em programas em que um int de 32 bits é muito diferente de um int de 64 bits. Alto nível sempre será portátil, é claro. Mas está longe de ser um C ++ generalização
rahmu
Eu acho que você pode ter entendido errado o que estou dizendo: você pode escrever C ++ correto com int ou qualquer tipo padrão sem se preocupar com coisas de baixo nível. Basta dar uma olhada nas bibliotecas de reforço, a maioria são apenas códigos de alto nível, e isso é verdade para muitos projetos de código aberto em C ++. Você "pode" diminuir o nível e, se o fizer, também pode evitar qualquer código específico até precisar usar a API específica da plataforma. Mas se você não precisar, pode escrever C ++ que funciona em qualquer lugar. A dependência da plataforma pode ser evitada e geralmente está no código da biblioteca.
precisa saber é o seguinte
Só para ter certeza, estou claro: não digo que todo o código C ++ seja portátil, estou dizendo que, como está, sua declaração está errada. Você pode querer corrigi-lo com algo como: "É aqui que o Java é muito diferente do C ++, onde cada aplicativo é" específico da máquina "e não pode ser portado sem modificar o código ou, se o código é realmente portátil e a compilação scripts gerenciam o novo destino, sem pelo menos uma compilação ".
precisa saber é o seguinte
14

Não é apenas a linguagem - são as bibliotecas.

Java e C ++ fornecem bibliotecas de plataforma cruzada. Java fornece um conjunto mais rico.

Andy Thomas
fonte
2
Java fornece um conjunto mais rico por padrão. As mesmas bibliotecas podem ser encontradas para C ++, elas simplesmente não fazem parte das bibliotecas padrão e você apenas precisa decidir quais usar (o que não é trivial, especialmente se elas não estiverem instaladas).
Martin York
Comparar as bibliotecas padrão de Java com o universo de bibliotecas para C ++ não é realmente uma comparação válida. Java fornece um conjunto mais rico, esteja você comparando as bibliotecas padrão de cada uma ou comparando o universo de bibliotecas de cada uma.
Andy Thomas
3
Definitivamente discordo disso. Tudo o que está disponível na biblioteca Java já está disponível para uso pelo C ++ em alguma biblioteca. Eu gosto do fato de o Java ter tudo em um só lugar, mas dizer que é mais rico simplesmente não é verdade. Talvez o adjetivo que você está procurando seja `` mais integrado ''
Martin York
1
+1 votaria novamente. Eu acho que as bibliotecas são o maior fator de portabilidade. Se você estiver trabalhando em C / C ++ e fazendo algo diferente de computação pura, haverá bibliotecas (em particular, partes da biblioteca do sistema) que são radicalmente diferentes entre Windows e Unix e sutilmente diferentes entre os diferentes tipos de Unix. Isso dificulta a portabilidade. Java basicamente não tem esse problema.
Tom Anderson
1
@ Andy Thomas-Cramer: Eu não estou comparando nada (você parece estar). Estou dizendo que sua declaração é imprecisa. Uma das vantagens que o Java tem (e todos gostamos disso) são todas as bibliotecas padrão em um só lugar. Dizer que eles são mais ricos simplesmente não é preciso.
Martin York
7

A diferença é que o Java será executado em qualquer plataforma sem recompilar. Ter um compilador C ++ para cada plataforma não é o mesmo.

Highland Mark
fonte
6

Todas as respostas que começam com "A diferença é ...", ou qualquer coisa muito semelhante, estão basicamente erradas (desculpe, mas a vida é assim). Na verdade, existem duas diferenças separadas entre os dois.

Uma (já mencionada muito) é que um programa Java compilado pode (ou pelo menos deve) ser executado em qualquer implementação em conformidade do Java; portanto, mesmo após a compilação, você ainda pode mover um programa Java de uma plataforma para outra sem precisar compilar novamente . C ++ (pelo menos normalmente) requer recompilação para cada plataforma de destino.

A outra é que o Java (pelo menos tenta) garantir que todo o Java corretamente escrito seja portátil. Pelo menos em teoria, você não deve conseguir escrever nenhum código que não seja portátil.

O C ++ permite que você faça várias coisas que não são portáteis. O padrão C ++ contém "avisos" sobre muitas coisas que não são portáveis ​​(por exemplo, informando que você obterá um comportamento definido de implementação ou um comportamento indefinido), mas não necessariamente tenta impedi-lo de fazê-lo. . Apenas por exemplo, se você deseja escrever um sistema operacional para hardware que usa um barramento PCI, provavelmente precisará ler / gravar a memória de configuração PCI. Obviamente, isso não será portátil para sistemas sem um barramento PCI, mas se você estiver escrevendo um sistema operacional para hardware com um barramento PCI, é praticamente necessário. O C ++ permite, mesmo que obviamente não seja portátil.

Jerry Coffin
fonte
C ++ não sabe nada sobre barramento PCI nem hardware.
Nikko
é claro que não, essas são coisas específicas da plataforma que deverão ser incluídas nas bibliotecas específicas da plataforma. Assim como o Java pode ter bibliotecas específicas da plataforma, se necessário.
jwenting
1
@ Nikko: Não sabe nada sobre isso, mas permite que você use o que sabe.
Jerry Coffin
@ jwenting: A diferença é que você pode escrever as bibliotecas específicas da plataforma em C ++, mas geralmente não é possível escrevê-las em Java.
Jerry Coffin
6

Você entendeu mal as instalações. Os programas Java são muito portáteis, porque a JVM fornece um comportamento padrão garantido para ser o mesmo. Os programas C ++ têm um ambiente menos padronizado mais próximo do hardware real, portanto, o programa precisa ser capaz de lidar com os vários detalhes específicos da plataforma - como tamanho de um int, alinhamento de palavras, etc, etc.

A própria JVM não é muito portátil. É uma tarefa hercúlea portar uma JVM de alto desempenho para outra plataforma ou arquitetura de CPU.


fonte
+1 para a última frase!
rahmu
2

A diferença é que os programas Java (não é um acrônimo) podem ser distribuídos de uma forma que pode ser executada em qualquer computador com uma JVM instalada, mas o C ++ é normalmente distribuído como código-fonte, o que é muito hostil para o usuário ou como um grupo. de binários diferentes para plataformas diferentes.

Colin
fonte
Hã? Existem compiladores C ++ direcionados à JVM e compiladores Java direcionados ao código nativo. Você pode citar a seção específica da especificação da linguagem C ++, que diz que os programas C ++ devem ser distribuídos como código fonte ou binários específicos da plataforma?
Jörg W Mittag
Lá, editei minha resposta para usar uma linguagem menos definitiva
Colin
2

Uma das razões pelas quais o Java é considerado portátil é que ele possui regras específicas sobre como as expressões aritméticas devem ser avaliadas e proíbe as implementações de avaliá-las de qualquer outra maneira, mesmo que avaliá-las da maneira exigida exigiria código mais lento do que avaliá-las de maneira mais precisa moda.

Por exemplo, dado

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

Os valores de thing1(2147483647)e thing2(1123456700,11234567.0f)devem ser -2147483649L e 99.9999923706054688, respectivamente, mesmo que os valores aritmeticamente corretos sejam 2147483647L e 100.0, e mesmo que em algumas plataformas o código para gerar resultados numericamente incorretos seja mais lento que o código para gerar o correto os resultados (em algumas plataformas de 64 bits, forçar o comportamento de quebra automática após (x + 1) exigiriam uma instrução extra, e na plataforma 8x87, forçar o valor de 1123456700 a ser arredondado para floatexigir uma instrução extra em comparação com o simples carregamento diretamente a um registro de precisão estendida).

supercat
fonte
1
Pela primeira vez, uma nova resposta para uma pergunta antiga que realmente acrescenta algo de valor: Java possui requisitos aritméticos muito precisos e, é claro, os tipos de dados primitivos têm tamanhos e semânticas específicos em comparação ao C ++. Nenhuma outra resposta até essa data menciona isso.
@ Snowman: Como você gosta dos exemplos específicos escolhidos? Pessoalmente, se eu estivesse projetando uma linguagem, eu não faria o exemplo retornar o valor do Java sem o uso de conversão de estreitamento (int)para a (x+1)subexpressão do primeiro exemplo no primeiro exemplo, para floato xparâmetro do segundo exemplo , mas obviamente eu não projetei a linguagem .
Supercat
Eu acho que eles fazem sentido. O importante para qualquer idioma é ter semântica bem definida. Independentemente de alguém concordar com uma determinada decisão de design de linguagem, o importante é poder examinar o código e saber como ele funciona. O Java geralmente faz isso, com poucos casos de comportamento indefinido.
1

A quantidade de trabalho para as ferramentas de suporte é realmente semelhante, a diferença está em outro lugar. Depois que um programa C ++ for compilado para uma plataforma, você precisará compilá-lo novamente se quiser usá-lo em uma plataforma diferente. No entanto, quando um programa java é compilado, você pode movê-lo para qualquer outra plataforma com um ambiente de tempo de execução sem precisar recompilar.


fonte
1

Respondendo ao título "Portabilidade é um mito?", Em vez de "Qual é melhor em portabilidade, Java ou C ++", direi que a portabilidade parcial é possível, mas a portabilidade total é um mito.

Algo que eu insisto em escrever, e se aplica a essa pergunta, é que os desenvolvedores não estão mais trabalhando apenas com linguagens de programação, mas com estruturas de programação completas.

E essas estruturas incluem bibliotecas, bancos de dados, interfaces gráficas.

Qual linguagem de programação ou qual estrutura de programação é mais portátil?

Bem, depende, qual é o seu aplicativo. está tentando alcançar.

umlcat
fonte
1

O problema é que você não escreve o JRE, você escreve o código Java que é executado em qualquer JRE. "Você" não escrever o código C ++ que pode exigir mudanças por você antes que ele irá compilar em outra plataforma.

James Anderson
fonte
0

Muitas pessoas esquecem ou não levam em conta a realidade do Java quando dizem que "é 100% portátil" ou frases como essa.

Praticamente todas as principais empresas de software / corporações tinham pelo menos uma implementação caseira de Java com um JRE associado no passado recente e algumas ainda o mantêm, Microsoft, IBM e Apple, por exemplo, tinham sua própria versão do Java refletindo seus próprias idéias e pensamentos sobre onde a indústria e essa linguagem devem ir.

Como é isso para "portátil"? Um JRE em qualquer lugar que você virar.

E isso sem considerar o que a Sun / Oracle estava fazendo.

Um exemplo de por que o código Java não está muito longe de C e C ++ em termos de portabilidade são as GUIs e os servidores gráficos, a Apple teve uma implementação não-padrão da estrutura da GUI para seu próprio JRE, como conseqüência, havia muitas dores de cabeça e trabalho duplo para quem quisesse criar / portar uma GUI usando Java para máquinas Apple e eles foram basicamente forçados a lidar com o Quartz (como é isso em termos de "alavancagem" e linguagens de alto nível?).

Às vezes, mesmo as palavras usadas mais comuns não refletem realmente o significado que as pessoas normalmente lhes dão, para mim o termo "portabilidade" no mundo Java é mais como "perspectiva" no senso comum; em termos comerciais e financeiros, há uma perspectiva melhor para você se você adotar o Java em vez de outras linguagens (pelo menos no momento em que o Java nasceu), porque você já tem muito trabalho feito de um lado (você obtém um JRE em qualquer coisa que pode ser considerado um "computador") e é provável que sua base de código seja portátil, pois você precisa de menos recursos para portar seu programa, é isso, se esse recurso é dinheiro, tempo ou mão de obra não importa, é menor limiar em comparação com outras tecnologias e é para isso que serve o Java, está diminuindo esse limiar.

É claro que isso é verdade se você aceitar as instalações do Java, o que significa uma máquina virtual com coleta de lixo, o que significa que ela consome mais recursos se comparada às linguagens nativas, se você realmente deseja extrair o máximo da CPU ou do farm de servidores I não pense que você pode adotar o Java, a menos que tenha poucos recursos ou a sua empresa seja muito pequena.

Ainda tenho que encontrar um único aplicativo Java não trivial que contenha apenas 1 versão para cada linha de código ou funcionalidade (também conhecida como nenhuma plataforma específica) e é 100% portátil entre os principais JREs.

user2485710
fonte