2009-01-11 6 views
6

Como dice la pregunta, ¿cuáles son algunos de los problemas más comunes que enfrentan los programadores de C++ al cambiar a Java? Estoy buscando algunos nombres de tema amplios o ejemplos y ajustes diarios que los ingenieros tuvieron que hacer. Entonces puedo ir y hacer una lectura profunda sobre esto.¿Cuáles son algunos riesgos/errores comunes de Java para el programador de C++?

Estoy especialmente interesado en las opiniones de los ingenieros que han trabajado en C++ durante años y han tenido que trabajar con Java, pero cualquier apuntador de otros o incluso recomendaciones de libros son más que bienvenidos.

Respuesta

15
  • En C++ usaría destructores para limpiar descriptores de archivos, conexiones de bases de datos y similares. El equivalente ingenuo es usar finalizadores. No lo hagas Nunca.

En lugar de utilizar este patrón:

OutputStream os; 
try { 
    os = ... 
    // do stuff 
} finally { 
    try { os.close(); } catch (Exception e) { } 
} 

Usted va a terminar haciendo cosas por el estilo mucho.

  • Si no especifica ningún modificador de acceso, en Java son los miembros del paquete-privados por defecto, a diferencia de C++ en las que son privadas. Package-private es un nivel de acceso molesto, lo que significa que es privado, pero cualquier cosa en el mismo paquete puede acceder a él también (que es un idiota nivel de acceso predeterminado imho);
  • No hay separación de pila/montón. Todo se crea en el montón (bueno, eso no es estrictamente cierto, pero lo fingiremos);
  • No hay referencias;
  • El equivalente a punteros a función es interfaces anónimas.
+1

Pasar por referencia/valor vale la pena leer sobre: ​​http://www.yoda.arachsys.com/java/passing.html – Dolph

3

Acostumbrándose a tener un recolector de basura. No poder confiar en un destructor para limpiar recursos que el GC no maneja.

Todo se pasa por valor, porque las referencias se pasan en lugar de objetos.

No hay copia del constructor, a menos que necesite clonar. Sin operador de asignación.

Todos los métodos son virtuales por defecto, que es lo opuesto a C++.

Soporte de lenguaje explícito para interfaces - clases virtuales puras en C++.

5

Generics (en lugar de plantillas), específicamente la forma en que se implementaron utilizando type erasure.

7

Mi mayor obstáculo al pasar de C++ a Java fue abandonar el código de procedimiento. Estaba muy acostumbrado a unir todos mis objetos dentro de los procedimientos. Sin código de procedimiento en java, hice referencias circulares en todas partes. Tuve que aprender cómo llamar objetos desde objetos sin que ellos sean dependientes el uno del otro. Fue el obstáculo más grande, pero el más fácil de superar.

Número 2 El problema personal es la documentación. JavaDoc es útil, pero muchos proyectos Java tienen el concepto erróneo de que todo lo que se necesita es JavaDoc. Vi mucha mejor documentación en proyectos de C++. Esto puede ser solo una preferencia personal para la documentación fuera del código.

Número 3.De hecho, hay punteros en java, simplemente no hay puntero aritmético. En java se llaman referencias. No piense que puede ignorar hacia dónde apuntan las cosas, regresará con un gran mordisco.

  • == y .equals no son iguales.

  • == mirará el puntero (referencia) mientras que .equals observará el valor al que apunta la referencia.

+0

puede ¿por favor explique el tipo de referencias circulares que puede usar en C++ pero no en Java? –

+0

Voy a editar para aclarar. Lo que estaba tratando de decir es que cuando comencé a codificar en java comencé a hacer referencias circulares porque no podía codificar procedimentalmente. Se considera, al menos por los desarrolladores que conozco, mala forma de hacer referencias circulares. – WolfmanDragon

2

Son todas las pequeñas diferencias de sintaxis que me dieron. La falta de destructores

Por otro lado, poder escribir una canción principal para cada clase (inmensamente útil o de prueba) es realmente agradable; después de que te acostumbras, la estructura y los trucos disponibles con los archivos jar son realmente agradables; el hecho de que la semántica esté completamente definida (por ejemplo, int es el mismo en todas partes) es realmente agradable.

5

Como mencionas las recomendaciones de libros, definitivamente lee Effective Java, 2nd ed., soluciona la mayoría de las trampas que he visto en las respuestas.

+0

Segundo esto. Este es un gran pequeño libro que está escrito para responder a las preguntas que tiene (riesgos, trampas y mejores prácticas). –

0

Todos los métodos son virtuales.

tipos parametrizados (genéricos) en realidad no crear código de código específico del parámetro (es decir, List<String> utiliza el mismo código de bytes como List<Object>; el compilador es el único que se queja si se intenta poner Integer en la antigua).

Varargs es fácil.

4
  • Sin herencia múltiple, y cada clase se deriva implícitamente de java.lang.Object (que tiene una serie de métodos importantes que sin duda tiene que saber y entender)
  • Puede tener una especie de herencia múltiple mediante la implementación interfaces
  • Sin sobrecarga del operador, excepto para '+' (para cadenas), y definitivamente ninguno puede hacerlo usted mismo
  • No hay tipos numéricos sin signo, excepto char, que no deberían usarse como tipo numérico. Si tiene que tratar con tipos sin firmar, tiene que hacer mucho fundido y enmascaramiento.
  • Las cadenas no tienen terminación nula, sino que están basadas en matrices de caracteres y, como tales, son inmutables. Como consecuencia de esto, construir una cadena larga añadiendo + = en un bucle es O (n^2), así que no lo hagas; use un StringBuilder en su lugar.
+0

Plus: no hay opción de 'pasar por valor' para los objetos. –

2

Mi peor problema fue tener en cuenta la propiedad de la memoria en todo momento. En C++, es algo necesario, y crea algunos patrones en la mente del desarrollador que son difíciles de superar. En Java, puedo olvidarlo (en un grado muy alto, de todos modos), y esto permite algunos algoritmos y enfoques que serían excesivamente incómodos en C++.

5

Creación de una referencia por accidente cuando uno estaba pensando en un constructor de copia:

myClass me = new myClass(); 
myClass somebodyElse = me; /* A reference, not a value copied into an independent instance! */ 
somebodyElse.setPhoneNumber(5551234); 
/* Hey... how come my phone doesn't work anymore?!?!? */ 
+0

Me imagino que un programador C es uno de los más equipados para entender esto, dada su relación íntima con los punteros y los valores de referencia. –

2

No hay objetos en Java, sólo hay referencias a objetos. Por ejemplo:

MyClass myClass; // no object is created unlike C++. 

Pero:

MyClass myClass = new MyClass(); // Now it is a valid java object reference. 
0

Especificación de un parámetro de método como definitiva no significa que lo que en un principio piensa que significa

private void doSomething(final MyObject myObj){ 
    ... 
    myObj.setSomething("this will change the obj in the calling method too"); 
    ... 
} 

porque es java paso por valor se haciendo lo que estás preguntando, no es inmediatamente obvio a menos que entiendas cómo java pasa el valor de la referencia en lugar del objeto.

0

Otro notable es la palabra clave final y const. Java define la const como una palabra reservada pero no especifica gran parte de su uso. También

object1=object2 

no copia los objetos que cambia la referencia

Cuestiones relacionadas