JavaRush /Blog Java /Random-ES /Errores de los programadores principiantes de Java. Parte...
articles
Nivel 15

Errores de los programadores principiantes de Java. Parte 1

Publicado en el grupo Random-ES

1. El nombre de la clase es diferente del nombre del archivo en el que está almacenada.

Todos los marcos de Java que he usado, incluidos los JDK de Javasoft, asumen que el código fuente de una clase con el modificador público se almacena en un archivo con exactamente el mismo nombre que el nombre de la clase y una extensión .java. No seguir esta convención puede causar muchos problemas que aparecerán durante la compilación.
Errores de los programadores principiantes de Java.  Parte 1 - 1
Los estudiantes principiantes (programadores) a menudo se olvidan de esta convención y, por ejemplo, configuran el nombre del archivo de acuerdo con la tarea: Lab6.java. Ejemplo incorrecto: nombre de archivoLab6.java
public class Airplane extends Vehicle
  Seat pilot;
  public Airplane() {
    pilot = new Seat();
  }
}
Ejemplo corregido: nombre de archivoAirplane.java
public class Airplane extends Vehicle
  Seat pilot;
  public Airplane() {
    pilot = new Seat();
  }
}
Tenga en cuenta:Se supone que el nombre de la clase comienza con una letra mayúscula. Los sistemas operativos que distinguen entre mayúsculas y minúsculas en los nombres de archivos pueden presentar problemas adicionales, especialmente para los estudiantes que aprenden Java en Unix y que están acostumbrados al sistema de nombres de archivos DOS. La clase MotorVehicledebe almacenarse en un archivo MotorVehicle.java, pero no en un motorvehicle.java.

2. Comparación usando==

En Java, las cadenas son objetos de la clase java.lang.String. ¡ El operador ==aplicado a los objetos comprueba la igualdad de referencias a los objetos! A veces los estudiantes no comprenden la semántica del operador ==e intentan utilizarlo para comparar cadenas. Ejemplo equivocado:
// проверим, es igual ли первый аргумент "-a"
if (args[0] == "-a") {
    optionsAll = true;
}
La forma correcta de comparar 2 cadenas para determinar la igualdad es utilizar el método equals()de clase java.lang.String. Devuelve truesi las cadenas tienen la misma longitud y contienen los mismos caracteres. (Nota: en realidad esto no garantiza la igualdad. De hecho, equalsverifica si 2 cadenas son iguales carácter por carácter) Ejemplo corregido:
//  проверим, es igual ли первый аргумент "-a"
if ("-a".equals(args[0])) {
    optionsAll = true;
}
Este error es una estupidez, porque en realidad el código Java resulta sintácticamente correcto, pero al final no funciona como se esperaba. Algunos estudiantes también intentan utilizar los operadores de comparación >y en lugar del <=método compareTo()de clase java.lang.String. Este error es más fácil de detectar porque provoca errores durante la fase de compilación.

3. Olvidé inicializar objetos que son elementos de la matriz.

En Java, una matriz de objetos es en realidad una matriz de referencias a objetos. Crear una matriz es simplemente crear un conjunto de referencias que no apuntan a nada (es decir, son nulas). Para crear realmente una matriz "completa" de objetos, es necesario inicializar cada elemento de la matriz. Muchos estudiantes no entienden esto; Creen que al crear una serie de objetos, automáticamente crean los objetos mismos. (En la mayoría de los casos, los estudiantes traen este concepto de C++, donde la creación de una matriz de objetos da como resultado la creación de los objetos ellos mismos llamando a su constructor predeterminado). En el siguiente ejemplo, el estudiante quiere crear 3 objetos de la clase StringBuffer. El código se compilará sin errores, pero se producirá una excepción en la última línea NullPointerException, donde se accede a un objeto inexistente. Ejemplo equivocado:
// Создаем массив из StringBuffer
StringBuffer [] myTempBuffers;
myTempBuffers = new StringBuffer[3];
myTempBuffers[0].add(data);
Para evitar este error, debe recordar inicializar los elementos de la matriz. Ejemplo corregido:
// Создаем массив из StringBuffer и инициализируем элементы
StringBuffer [] myTempBuffers;
myTempBuffers = new StringBuffer[3];
for (int ix = 0; ix < myTempBuffers.length; ix++)
     myTempBuffers[ix] = new StringBuffer();

myTempBuffers[0].add(data);

4. Colocar varias clases con un modificador en un archivo a la vezpublic

Los archivos fuente de Java están asociados de cierta manera con las clases contenidas en esos archivos. La relación se puede caracterizar de la siguiente manera: cualquier clase Java se almacena en no más de un archivo. En cualquier archivo de código fuente no puedes colocar más de 1 clase con el modificador public. Si hay una clase con un modificador en el archivo de código fuente public, el nombre del archivo y el nombre de la clase deben ser estrictamente iguales (nota de traducción: hasta el caso, consulte el punto 1) A veces los estudiantes se olvidan de la segunda regla, lo que genera errores en la etapa de compilación. El mensaje de error para la segunda y tercera regla será el mismo (que es lo que realmente dificulta reconocer este error).

5. Sustitución de un campo de clase por una variable local.

Java te permite declarar variables dentro de un método cuyo nombre coincida con los campos de la clase. En este caso, las variables locales tendrán prioridad y se utilizarán en lugar de campos. El compilador arrojará un error si las variables con el mismo nombre son de diferentes tipos. Si son del mismo tipo, no habrá error de compilación y las razones del funcionamiento incorrecto del programa no estarán claras. Ejemplo equivocado:
public class Point3 {
    int i = 0;
    int j = 0;
    int k = 0;

    public boolean hits(Point[] p2list) {
      for(int i = 0; i < p2list.length; i++) {
        Point p2 = p2list[i];
        if (p2.x == i && p2.y == j)
          return true;
      }
      return false;
    }
}
Hay varias formas de corregir este error. La más sencilla es acceder a los campos de clase utilizando un puntero implícito this: this.Nombre_поля. La mejor manera es cambiar el nombre del campo de clase o de la variable local, entonces no se producirá la sustitución. (aprox. Transl.: El segundo método no es nuestro método. Además, no garantiza que algún día no reemplazaré accidentalmente un campo de una variable. Una dificultad aún mayor surge con la herencia, cuando no veo en absoluto qué campos la clase tiene ) Ejemplo corregido:
// One way to fix the problem
  int i = 0;
  int j = 0;
  int k = 0;

  public boolean hits(Point[] p2list) {
    for(int i = 0; i < p2list.length; i++) {
      Point p2 = p2list[i];
      if (p2.x == this.i && p2.y == this.j)
        return true;
    }
    return false;
  }

  // *****************************
  // Лучший способ
  int x = 0;
  int y = 0;
  int z = 0;

  public boolean hits(Point[] p2list) {
    for(int i = 0; i < p2list.length; i++) {
      Point p2 = p2list[i];
      if (p2.x == x && p2.y == y)
        return true;
    }
    return false;
  }
Otro lugar posible para que ocurra este error es configurando el nombre del parámetro del método para que sea el mismo que el nombre del campo de clase. Esto se ve bien en constructores, pero no es adecuado para métodos normales.

aprox. traducción

un poco caótico, pero esa es la esencia

public class Test {
   private int param = 0;

   public Test(int param) {
      this.param = param;
   }
}

es decir, todo se ve hermoso en el constructor, pero esto no debe usarse para métodos ordinarios.

6. Olvidé llamar al constructor principal (superclase)

Cuando una clase extiende a otra clase, cada constructor de subclase debe llamar a algún constructor de superclase. Esto generalmente se logra llamando al constructor de la superclase con el método super(x)ubicado en la primera línea del constructor. Si no hay ninguna llamada en la primera línea del constructor super(x), el propio compilador inserta esta llamada, pero sin parámetros: super(). (traducción aproximada: x...se, pero no lo sabía) A veces los estudiantes se olvidan de este requisito. Por lo general, esto no es un problema: el compilador inserta la llamada al constructor de la superclase y todo funciona bien. Sin embargo, si la superclase no tiene un constructor predeterminado, el compilador arrojará un error. En el siguiente ejemplo, todos los constructores de superclases java.io.Filetienen 1 o 2 parámetros: Ejemplo erróneo:
public class JavaClassFile extends File {
    String classname;
    public JavaClassFile(String cl) {
        classname = cl;
    }
}
La solución al problema es insertar una llamada explícita al constructor de superclase correcto: Ejemplo corregido:
public class JavaClassFile extends File {
    String classname;
    public JavaClassFile(String cl) {
        super(cl + ".class");
        classname = cl;
    }
}
Una situación más desagradable ocurre cuando la superclase tiene un constructor predeterminado, pero no inicializa completamente el objeto. En este caso, el código se compilará, pero el resultado del programa puede ser incorrecto o puede ocurrir una excepción.

7. Detectar excepciones incorrectamente

El sistema de manejo de excepciones de Java es bastante poderoso, pero difícil de entender para los principiantes. Los estudiantes que dominan C++ o Ada generalmente no tienen las mismas dificultades que los programadores de C y Fortran. Los siguientes ejemplos muestran algunos errores comunes. En este ejemplo, la excepción no tiene nombre. El compilador indicará este error en la etapa de compilación, por lo que es fácil solucionarlo usted mismo. Ejemplo equivocado:
try {
    stream1 = new FileInputStream("data.txt");
} catch (IOException) {
    message("Could not open data.txt");
}
Ejemplo corregido:
try {
   stream1 = new FileInputStream("data.txt");
} catch (IOException ie) {
   message("Could not open data.txt: " + ie);
}
El orden de los bloques catchdetermina el orden en que se detectan las excepciones. Debe tenerse en cuenta que cada uno de estos bloques detectará todas las excepciones de la clase especificada o cualquiera de sus subclases. Si no tiene esto en cuenta, puede terminar con un bloque catch inalcanzable, que el compilador señalará. En el siguiente ejemplo SocketExceptionhay una subclase de IOException. Ejemplo equivocado:
try {
    serviceSocket.setSoTimeout(1000);
    newsock = serviceSocket.accept();
} catch (IOException ie) {
    message("Error accepting connection.");
} catch (SocketException se) {
    message("Error setting time-out.");
}
Ejemplo corregido:
try {
    serviceSocket.setSoTimeout(1000);
    newsock = serviceSocket.accept();
} catch (SocketException se) {
    message("Error setting time-out.");
} catch (IOException ie) {
    message("Error accepting connection.");
}
Si es posible que ocurra una excepción en su código que no sea detectada por ningún bloque try-catch, entonces esta excepción debe declararse en el encabezado del método. RuntimeException( Esto no es necesario para excepciones: subclases de una clase ). A veces los estudiantes olvidan que llamar a un método puede generar una excepción. La forma más sencilla de solucionar este problema es colocar la llamada al método en un bloque try-catch. Ejemplo equivocado:
public void waitFor(int sec) {
    Thread.sleep(sec * 1000);
}
Ejemplo corregido:
public void waitFor(int sec) throws InterruptedException {
    Thread.sleep(sec * 1000);
}

8. El método de acceso tiene un tipo.void

Este es un error muy simple. El estudiante crea un método para acceder a una variable, pero especifica que el método no devuelve nada (coloca un modificador voiden el encabezado del método). Para corregir este error, debe especificar el tipo de devolución correcto. Ejemplo equivocado:
public class Line {
    private Point start, end;
    public void getStart() {
      return start;
    }
}
Ejemplo corregido:
public class Line {
    private Point start, end;
    public Point getStart() {
      return start;
    }
}
Especificar el tipo de devolución incorrecto genera toda una clase de errores. Normalmente, el compilador reconocerá estos errores y los informará para que los estudiantes puedan corregirlos ellos mismos. Autor: A. Grasoff™ Lea la continuación Enlace a la fuente: Errores de los programadores principiantes de Java
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION