Hola Quiero llamar su atención sobre un breve artículo. Este artículo está destinado a principiantes. Pero incluso si es un desarrollador experimentado, no saque conclusiones precipitadas.
Espero que esta publicación sea útil no solo para principiantes.
El propósito de esta publicación:Muestra los errores más comunes para principiantes y algunos trucos para solucionarlos. Está claro que algunos errores pueden ser complejos y ocurrir por una razón u otra. El propósito de la publicación es, en cierta medida, analizarlos y ayudar a identificarlos en una etapa temprana. Espero que esta publicación sea útil para principiantes.
Lista de verificación de errores:
1. Errores tipográficos. Errores tipográficos molestos que no aparecen de inmediato
2. Asignación en condición en lugar de comparación
3. Errores lógicos en la condición.
4. Comparación de cadenas incorrectas
5. Inicialización incorrecta de variables de tipos primitivos.
6. Uso indebido de doble
7. Tipo incorrecto de valor de retorno en el constructor.
8. División por cero. POSITIVO_INFINIDAD
9. Sin tener en cuenta el orden de inicialización de la clase.
10. Una variable local oculta una variable de clase
11. Ignorando la conversión automática en expresiones aritméticas
12. Bucle infinito con byte, que es difícil de detectar.
13. El nombre de la clase es diferente del nombre del archivo en el que está almacenado.
14. Los objetos que son elementos de una matriz no se inicializan.
15. Colocar varias clases en un archivo a la vez con el modificador público
Problemas de Java
Todos los lenguajes de programación tienen sus ventajas y desventajas. Esto se debe a muchas razones. Java no es la excepción. Traté de recopilar algunas dificultades obvias y no obvias encontradas por un programador Java novato. Estoy seguro de que los programadores experimentados también encontrarán algo útil en mi artículo. La práctica, la atención y la experiencia adquirida en programación te ayudarán a salvarte de muchos errores. Pero algunos errores y dificultades se consideran mejor de antemano. Daré algunos ejemplos con código y explicaciones. Muchas explicaciones te resultarán claras a partir de los comentarios sobre el código. La práctica da mucho, ya que algunas reglas no son tan obvias. Algunos yacen en la superficie, otros están ocultos en las bibliotecas de idiomas o en la máquina virtual de Java. Recuerde que Java no es solo un lenguaje de programación con un conjunto de bibliotecas, sino que también es una máquina virtual Java.
Para el artículo, escribí específicamente un código de trabajo con comentarios detallados. Para escribir un artículo con ejemplos de código, se utilizó Java 8. Para las pruebas, el código Java se coloca en paquetes separados.
Ejemplo: "package underwaterRocks.simple;"
¿Qué dificultades enfrentan los principiantes?
Errores tipográficos
Sucede que los programadores novatos hacen errores tipográficos que son difíciles de detectar de un vistazo.
Ejemplo de código:Archivo: "Simple.java"
package underwaterRocks.simple; public class Simple { public static void main(String[] args) { int ival = 10; if(ival>0); { System.out.println(" "); } } }
Explicación : “El punto y coma indica el final de la declaración. En este caso; Es el final de una declaración vacía. Este es un error lógico. Tal error puede ser difícil de detectar.
El compilador considerará que todo es correcto. Condición if (ival> 0); En este caso no tiene sentido. Porque significa: si ival es más que cero, no haga nada y continúe ".
Asignación en condición en lugar de comparación
La condición es la asignación variable.
Esto no es un error, pero el uso de dicha técnica debe estar justificado.
boolean myBool = false; if(myBool = true) System.out.println(myBool);
En este código, si (myBool = true) significa: "Establezca la variable myBool en true,
si la expresión es verdadera, entonces siga la condición que sigue a los corchetes ".
En este código, la condición siempre será verdadera. Y System.out.println (myBool); siempre se ejecutará, independientemente de la condición.
== es una comparación para la igualdad.
= Es una tarea, puedes decir a = 10; como: "pero asigna un valor de 10".
La condición entre paréntesis devuelve un valor booleano.
No importa en qué orden escribas. Puede comparar así: (0 == a) o (5 == a)
Si olvida un signo igual, por ejemplo (0 = a) o (5 = a), el compilador le notificará un error. Usted asigna un valor, no una comparación.
También puede escribir de forma legible algún intervalo.
Por ejemplo: necesita escribir: mayor que 5 y menor que 10.
Escribes así: (a> 4 && a <10), pero con el mismo éxito puedes escribir: (4 <a && a <10),
ahora ve que a está entre 4 y 10, excluyendo estos valores. Esto es más obvio. Es inmediatamente evidente que, a está en el intervalo entre 4 y 10, excluyendo estos valores.
Ejemplo de código (intervalo) 3.9 [):
if (3 <a && a <9) ejecutar;
Error lógico
if (condición) {} if (condición) {} else {} - else se refiere al if más cercano.
Esta es a menudo la causa de los errores de principiante.
Comparación de cadenas no válida
Los principiantes a menudo usan == en lugar de .equals para comparar cadenas.
Inicialización variable
Considere inicializar variables de un tipo primitivo.
Primitivas (byte, short, int, long, char, float, double, boolean).
Valores iniciales
byte 0 short 0 int 0 long 0L float 0.0f double 0.0d char '\u0000' String (or any object) null boolean false ( jvm)
Nota:Las variables locales son ligeramente diferentes;
El compilador nunca asigna un valor predeterminado a una variable local no inicializada.
Si no puede inicializar su variable local donde se declara,
Recuerde asignarle un valor antes de intentar usarlo.
El acceso a una variable local no inicializada dará como resultado un error en tiempo de compilación.
Confirmación de esta nota en código:Archivo: "MyInitLocal.java"
package underwaterRocks.myInit; public class MyInitLocal { float classes_f; int classes_gi; public static void main(String[] args) { float f; int i; MyInitLocal myInit = new MyInitLocal(); System.out.println("myInit.classes_f = " + myInit.classes_f); System.out.println("myInit.classes_gi = " + myInit.classes_gi);
Rangos de valores:
byte ( , 1 , [-128, 127])
short ( , 2 , [-32768, 32767])
int ( , 4 , [-2147483648, 2147483647])
long ( , 8 , [-922372036854775808,922372036854775807])
float ( , 4 )
double ( , 8 )
char ( Unicode, 2 , 16 , [0, 65535])
boolean ( /, int, JVM)
char: el tipo de datos char es un único carácter Unicode de 16 bits. Tiene un valor mínimo de '\ u0000' (o 0) y un valor máximo de '\ uffff' (o 65,535 inclusive).
Documentación de Oracle
>>Intentemos inicializar una variable de tipo long con el número: 922372036854775807.
Nada nos saldrá bien. Porque, es un literal entero de tipo int.
Inicialización correcta con un literal largo: 922372036854775807L;
Ejemplo de código:Archivo: "MyInitLocalLong.java"
package underwaterRocks.myInit; public class MyInitLocalLong { public static void main(String[] args) {
Qué buscar al inicializar una variable.
El rango de valores de una variable de este tipo. El hecho de que la variable se inicializa con un literal de cierto tipo. Para moldes explícitos e implícitos. Sobre compatibilidad de tipos.
Cuando utilice shells de tipo Integer, debe prestar atención al autoembalaje y desembalaje automático de estos tipos.
Uso inapropiado de doble
Aquí necesitas aclarar. No se trata de mal uso del tipo doble.
Usamos correctamente Solo el resultado puede sorprender a un programador novato.
Archivo: "MinusDouble.java"
package underwaterRocks.tstDouble; public class MinusDouble { public static void main(String[] args) { double a = 4.64; double b = 2.64; System.out.println("ab = "+(ab)); } }
Nota sobre el tipo doble. Un punto flotante le permite contar con un error relativo dado y un rango enorme. En los cálculos científicos, a menudo se necesita un error relativo.
Doble comparación inválida
Considere el tipo doble.
Ejemplo de código:Archivo: "MyDouble.java"
package underwaterRocks.myDouble; public class MyDouble { public static void main(String[] args) { double dx = 1.4 - 0.1 - 0.1 - 0.1 - 0.1; System.out.println("dx = " + dx);
El tipo doble es conveniente donde no se necesita alta precisión. Para transacciones financieras, este tipo no es adecuado. Aunque algunas compañías, no muy honestas, usan el tipo doble para redondear al lado que necesitan. Para las operaciones financieras, la clase BigDecimal se usa en los cálculos financieros, ya que los tipos primitivos reales no son adecuados para este propósito debido a razones de pérdida de precisión y errores en los resultados de redondeo. Sin embargo, se obtienen resultados más precisos utilizando la clase BigInteger.
Constructor de clase
El constructor de la clase coincide con el nombre de la clase y no devuelve nada, ni siquiera nulo.
Ejemplo de código:Archivo: "MyConstructor.java"
package underwaterRocks.myConstructor; public class MyConstructor { public MyConstructor(){ System.out.println(" void"); } public void MyConstructor(){ System.out.println(" c void"); } public static void main(String[] args) { MyConstructor myconst = new MyConstructor(); myconst.MyConstructor();
Como vemos en el código, dos métodos con los mismos nombres: MyConstructor () y MyConstructor (). Uno de los métodos no devuelve nada. Este es el constructor de nuestra clase. Otro método con void es el método de clase regular. En el caso de que no haya creado un constructor o, en su opinión, haya creado un constructor de clase con void, el compilador creará un constructor predeterminado y se sorprenderá de por qué su constructor no funciona.
División por cero
¿Cuál cree que será el resultado de la ejecución de dicho código?
Archivo: "DivisionByZero.java"
package divisionByZero; import static java.lang.Double.POSITIVE_INFINITY; public class DivisionByZero { public static void main(String[] args) { try{ float f = 12.2f; double d = 8098098.8790d; System.out.println(f/0); System.out.println(d/0); System.out.println(POSITIVE_INFINITY == f/0); System.out.println(POSITIVE_INFINITY == d/0); } catch (NumberFormatException ex) { System.out.println("NumberFormatException"); } catch (ArithmeticException ex) { System.out.println("ArithmeticException"); } } }
La ejecución del código generará:
Infinity Infinity true true
Dividir el tipo entero por cero dará una ArithmeticException.
La clase java.lang.Double define la constante
POSITIVE_INFINITY;
public static final float POSITIVE_INFINITY = 1.0d / 0.0d;
Se convierte en una cadena igual a Infinito.
Orden de inicialización
Archivo: "InitClass.java"
package myInitClass; public class InitClass { InitClass(){
Primero, se ejecutan todos los bloques estáticos, luego los bloques de inicialización, luego el constructor de la clase.
Se mostrará: "123 Constructor"
Una variable local oculta una variable de clase.Aunque los IDE modernos detectan fácilmente dicho error, me gustaría considerarlo con más detalle. Comencemos con la asignación de variable clásica en el constructor. El ejemplo es correcto. No hay error
public class MyClass { private int val = 0; public MyClass(int val) { this.val = val; } }
Sin embargo, ¿qué sucede si usa esta técnica en un método y no en un constructor de clases? En el método habitual, no se recomienda usar esta técnica. La pregunta se relaciona con el diseño adecuado de una clase.
Una explicación simple: en un método, una variable con el mismo nombre que una variable de clase es local para el método. Puede acceder a la variable de clase usando this.val. Sin embargo, tal atractivo del método, si la clase está diseñada incorrectamente, solo causará efectos secundarios y puede degradar la legibilidad del código.
La conversión de tipo aritmético se realiza automáticamenteEsto puede causar errores molestos.
Una posible solución cuando se trabaja con una cadena:
byte bHundr = Byte.parseByte("100");
Otro error se da en el siguiente código.
for (byte i = 1; i <= 128; i++) { System.out.println(i); }
En este caso, obtenemos un bucle infinito.
La explicacion. Escriba el byte [-128, 127]. 128 ya no está en este rango. Se produce un desbordamiento y el ciclo se repite. La necesidad de usar byte en este caso es dudosa. Aunque tiene lugar en casos raros. La recomendación es usar int en lugar de byte. Otra recomendación es no usar un bucle en su algoritmo.
Los objetos que son elementos de matriz no se inicializan int[] cats = new int[10]; for(int i=0; i<cats.length;i++){ System.out.println("cats " + i + " = " + cats[i]); }
En este ejemplo, tenemos una matriz de elementos de tipo primitivos. Y no pasa nada malo cuando no los inicializamos. Se les asignará el valor predeterminado. En este caso, el valor = 0.
Consideremos otro ejemplo, no con primitivas en la matriz, sino con objetos en la matriz.
public class ArrInitObj { public static void main(String[] args) { MyObj[] cats = new MyObj[10]; for(int i=0; i<cats.length;i++){ System.out.println("cats " + i + " = " + cats[i]); System.out.println("cats " + i + ".val = " + cats[i].val);
La solución a este problema es inicializar todas las variables de objeto antes de usarlas. La inicialización se puede hacer en el constructor de la clase MyObj.
El nombre de la clase es diferente del nombre del archivo en el que está almacenado.El IDE moderno detecta fácilmente este tipo de error. Sin embargo, tales errores se encuentran, aunque muy raramente. Esto ayudará a la atención, teniendo en cuenta las diferencias en los nombres de letras mayúsculas y minúsculas.
Colocando varias clases en un archivo a la vez con el modificador públicoEl error es bastante raro. El IDE le dará inmediatamente una advertencia.
El nombre del archivo debe coincidir con el nombre de la clase pública.
ConclusionesMuchos errores no son obvios a primera vista. Incluso los programadores experimentados los hacen, pero en menor número. La atención, la experiencia práctica, el uso de un depurador y la lectura de la documentación lo ayudarán a evitar muchos errores.
Espero que hayas disfrutado el artículo y lo hayas encontrado útil. Estaré encantado de sus comentarios, comentarios, sugerencias, deseos. Continuará Más bien, la adición sigue.
ReferenciasDirectrices de diseño del código Oracle Java >>>PS. Mis amigos No tengo forma de seguir publicando sin su ayuda. Es decir, no hay oportunidad financiera. Si la publicación realmente te ayudó y quieres continuar, por favor apóyame. En alguna parte hay un botón: "Apoya al autor".
Espero tu comprensión. Gracias Gracias a Habr por la oportunidad de publicar.
El autor se verá obligado a eliminar sus publicaciones u ocultarlas en borradores en caso de falta de apoyo. Esto no es un ultimátum. Si tiene la oportunidad, fue útil, puede ayudar, luego haga clic en el botón de soporte del autor.