JavaRush /Blog Java /Random-FR /Erreurs des programmeurs Java débutants. Partie 1
articles
Niveau 15

Erreurs des programmeurs Java débutants. Partie 1

Publié dans le groupe Random-FR

1. Le nom de la classe est différent du nom du fichier dans lequel elle est stockée

Tous les frameworks Java que j'ai utilisés, y compris les JDK Javasoft, supposent que le code source d'une classe avec le modificateur public est stocké dans un fichier portant exactement le même nom que le nom de la classe et une extension .java. Le non-respect de cette convention peut entraîner de nombreux problèmes qui apparaîtront lors de la compilation.
Erreurs des programmeurs Java débutants.  Partie 1 - 1
Les étudiants débutants (programmeurs) oublient souvent cette convention et, par exemple, définissent le nom du fichier conformément au devoir : Lab6.java. Mauvais exemple : nom de fichierLab6.java
public class Airplane extends Vehicle
  Seat pilot;
  public Airplane() {
    pilot = new Seat();
  }
}
Exemple corrigé : Nom de fichierAirplane.java
public class Airplane extends Vehicle
  Seat pilot;
  public Airplane() {
    pilot = new Seat();
  }
}
Veuillez noter:le nom de la classe est supposé commencer par une lettre majuscule. Les systèmes d'exploitation qui respectent la casse dans les noms de fichiers peuvent présenter des problèmes supplémentaires, en particulier pour les étudiants apprenant Java sous Unix et habitués au système de dénomination de fichiers DOS. La classe MotorVehicledoit être stockée dans un fichier MotorVehicle.java, mais pas dans un fichier motorvehicle.java.

2. Comparaison utilisant==

En Java, les chaînes sont des objets de la classe java.lang.String. L'opérateur ==appliqué aux objets vérifie l'égalité des références aux objets ! Parfois, les étudiants ne comprennent pas la sémantique de l'opérateur ==et essaient de l'utiliser pour comparer des chaînes. Mauvais exemple :
// проверим, equals ли первый аргумент "-a"
if (args[0] == "-a") {
    optionsAll = true;
}
La bonne façon de comparer 2 chaînes pour l’égalité est d’utiliser la méthode equals()de classe java.lang.String. Il renvoie truesi les chaînes ont la même longueur et contiennent les mêmes caractères. (Remarque : en réalité cela ne garantit pas l'égalité. En fait, equalsil vérifie si 2 chaînes sont égales caractère par caractère) Exemple corrigé :
//  проверим, equals ли первый аргумент "-a"
if ("-a".equals(args[0])) {
    optionsAll = true;
}
Cette erreur est stupide, car en fait le code Java s'avère syntaxiquement correct, mais au final il ne fonctionne pas comme prévu. Certains étudiants essaient également d'utiliser des opérateurs de comparaison >et <=des méthodes compareTo()de classe java.lang.String. Cette erreur est plus facile à détecter car elle provoque des erreurs lors de la phase de compilation.

3. J'ai oublié d'initialiser les objets qui sont des éléments du tableau.

En Java, un tableau d’objets est en réalité un tableau de références d’objets. Créer un tableau consiste simplement à créer un ensemble de références qui ne pointent vers rien (c'est-à-dire qu'elles sont nulles). Pour créer réellement un tableau "complet" d'objets, vous devez initialiser chaque élément du tableau. De nombreux étudiants ne comprennent pas cela ; ils croient qu'en créant un ensemble d'objets, ils créent automatiquement les objets eux-mêmes. (Dans la plupart des cas, les étudiants apportent ce concept du C++, où la création d'un tableau d'objets aboutit à la création des objets eux-mêmes en appelant leur constructeur par défaut.) Dans l'exemple ci-dessous, l'élève souhaite créer 3 objets de la classe StringBuffer. Le code sera compilé sans erreur, mais une exception se produira dans la dernière ligne NullPointerException, où l'on accède à un objet inexistant. Mauvais exemple :
// Создаем массив из StringBuffer
StringBuffer [] myTempBuffers;
myTempBuffers = new StringBuffer[3];
myTempBuffers[0].add(data);
Pour éviter cette erreur, vous devez penser à initialiser les éléments du tableau. Exemple corrigé :
// Создаем массив из StringBuffer и инициализируем элементы
StringBuffer [] myTempBuffers;
myTempBuffers = new StringBuffer[3];
for (int ix = 0; ix < myTempBuffers.length; ix++)
     myTempBuffers[ix] = new StringBuffer();

myTempBuffers[0].add(data);

4. Placer plusieurs classes avec un modificateur dans un seul fichier à la foispublic

Les fichiers sources Java sont associés d'une certaine manière aux classes contenues dans ces fichiers. La relation peut être caractérisée comme suit : Toute classe Java est stockée dans un seul fichier au maximum. Dans n'importe quel fichier de code source, vous ne pouvez pas placer plus d'une classe avec le modificateur public. S'il y a une classe avec un modificateur dans le fichier de code source public, le nom du fichier et le nom de la classe doivent être strictement identiques (note de traduction : jusqu'à la casse, voir point 1) Parfois les étudiants oublient la 2ème règle, ce qui entraîne des erreurs à la compilation sur scène. Le message d'erreur pour les 2ème et 3ème règles sera le même (c'est ce qui rend difficile la reconnaissance de cette erreur).

5. Substitution d'un champ de classe par une variable locale.

Java permet de déclarer des variables à l'intérieur d'une méthode dont le nom correspond aux champs de la classe. Dans ce cas, les variables locales auront priorité et seront utilisées à la place des champs. Le compilateur générera une erreur si les variables portant les mêmes noms sont de types différents. S’ils sont du même type, il n’y aura pas d’erreur de compilation et les raisons du mauvais fonctionnement du programme ne seront pas claires. Mauvais exemple :
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;
    }
}
Il existe plusieurs façons de corriger cette erreur. Le plus simple est d'accéder aux champs de classe en utilisant le pointeur implicitethis : this.Name_поля. Le meilleur moyen est de renommer le champ de classe ou la variable locale, la substitution n'aura alors pas lieu. (traduction approximative : La 2ème méthode n'est pas notre méthode. De plus, elle ne garantit pas que je ne remplacerai pas accidentellement un champ d'une variable un jour. Une difficulté encore plus grande survient avec l'héritage, lorsque je ne vois pas du tout quels champs la classe a ) Exemple corrigé :
// 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;
  }
Cette erreur peut également se produire en définissant le nom du paramètre de méthode pour qu'il soit identique au nom du champ de classe. Cela semble bien dans les constructeurs, mais ne convient pas aux méthodes normales.

environ. traduction

un peu chaotique, mais c'est l'essentiel

public class Test {
   private int param = 0;

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

c'est-à-dire que tout est beau dans le constructeur, mais cela ne doit pas être utilisé pour les méthodes ordinaires.

6. J'ai oublié d'appeler le constructeur parent (superclasse)

Lorsqu'une classe étend une autre classe, chaque constructeur de sous-classe doit appeler un constructeur de superclasse. Ceci est généralement réalisé en appelant le constructeur de superclasse avec la méthode super(x)placée sur la première ligne du constructeur. S'il n'y a pas d'appel dans la première ligne du constructeur super(x), le compilateur insère lui-même cet appel, mais sans paramètres : super(). (trans. approx. : x...se, mais je ne savais pas) Parfois les étudiants oublient cette exigence. Habituellement, ce n'est pas un problème : l'appel au constructeur de la superclasse est inséré par le compilateur et tout fonctionne bien. Cependant, si la superclasse n'a pas de constructeur par défaut, le compilateur générera une erreur. Dans l'exemple ci-dessous, tous les constructeurs de superclasses java.io.Fileont 1 ou 2 paramètres : Exemple erroné :
public class JavaClassFile extends File {
    String classname;
    public JavaClassFile(String cl) {
        classname = cl;
    }
}
La solution au problème est d'insérer un appel explicite au constructeur de superclasse correct : Exemple corrigé :
public class JavaClassFile extends File {
    String classname;
    public JavaClassFile(String cl) {
        super(cl + ".class");
        classname = cl;
    }
}
Une situation plus désagréable se produit lorsque la superclasse a un constructeur par défaut, mais qu'elle n'initialise pas complètement l'objet. Dans ce cas, le code sera compilé, mais la sortie du programme peut être incorrecte ou une exception peut se produire.

7. Détection incorrecte des exceptions

Le système de gestion des exceptions de Java est assez puissant, mais difficile à comprendre pour les débutants. Les étudiants maîtrisant C++ ou Ada n'ont généralement pas les mêmes difficultés que les programmeurs C et Fortran. Les exemples ci-dessous montrent quelques erreurs courantes. Dans cet exemple, l'exception n'est pas nommée. Le compilateur indiquera cette erreur au stade de la compilation, il est donc facile de la corriger vous-même. Mauvais exemple :
try {
    stream1 = new FileInputStream("data.txt");
} catch (IOException) {
    message("Could not open data.txt");
}
Exemple corrigé :
try {
   stream1 = new FileInputStream("data.txt");
} catch (IOException ie) {
   message("Could not open data.txt: " + ie);
}
L'ordre des blocs catchdétermine l'ordre dans lequel les exceptions sont interceptées. Il faut tenir compte du fait que chacun de ces blocs interceptera toutes les exceptions de la classe spécifiée ou de l'une de ses sous-classes. Si vous n'en tenez pas compte, vous risquez de vous retrouver avec un bloc catch inaccessible, que le compilateur vous signalera. Dans l'exemple ci-dessous, SocketExceptionil s'agit d'une sous-classe de IOException. Mauvais exemple :
try {
    serviceSocket.setSoTimeout(1000);
    newsock = serviceSocket.accept();
} catch (IOException ie) {
    message("Error accepting connection.");
} catch (SocketException se) {
    message("Error setting time-out.");
}
Exemple corrigé :
try {
    serviceSocket.setSoTimeout(1000);
    newsock = serviceSocket.accept();
} catch (SocketException se) {
    message("Error setting time-out.");
} catch (IOException ie) {
    message("Error accepting connection.");
}
S'il est possible qu'une exception se produise dans votre code qui n'est interceptée par aucun block try-catch, alors cette exception doit être déclarée dans l'en-tête de la méthode. RuntimeException( Ceci n'est pas nécessaire pour les exceptions - sous-classes d'une classe ). Les étudiants oublient parfois que l’appel d’une méthode peut lever une exception. Le moyen le plus simple de résoudre ce problème est de placer l'appel de méthode dans un bloc try-catch. Mauvais exemple :
public void waitFor(int sec) {
    Thread.sleep(sec * 1000);
}
Exemple corrigé :
public void waitFor(int sec) throws InterruptedException {
    Thread.sleep(sec * 1000);
}

8. La méthode d'accès a un typevoid

C'est une erreur très simple. L'étudiant crée une méthode pour accéder à une variable, mais précise que la méthode ne renvoie rien (place un modificateur voiddans l'entête de la méthode). Pour corriger cette erreur, vous devez spécifier le type de retour correct. Mauvais exemple :
public class Line {
    private Point start, end;
    public void getStart() {
      return start;
    }
}
Exemple corrigé :
public class Line {
    private Point start, end;
    public Point getStart() {
      return start;
    }
}
Spécifier un mauvais type de retour génère toute une classe d’erreurs. Généralement, le compilateur reconnaît ces erreurs et les signale afin que les étudiants puissent les corriger eux-mêmes. Auteur : A. Grasoff™ Lire la suite Lien vers la source : Erreurs des programmeurs Java débutants
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION