JavaRush /Blogue Java /Random-PT /Erros de programadores Java iniciantes. Parte 1
articles
Nível 15

Erros de programadores Java iniciantes. Parte 1

Publicado no grupo Random-PT

1. O nome da classe é diferente do nome do arquivo no qual ela está armazenada

Todas as estruturas Java que usei, incluindo os Javasoft JDKs, assumem que o código-fonte de uma classe com o modificador público está armazenado em um arquivo com exatamente o mesmo nome da classe e uma extensão .java. O não cumprimento desta convenção pode causar muitos problemas que aparecerão durante a compilação.
Erros de programadores Java iniciantes.  Parte 1 - 1
Alunos iniciantes (programadores) muitas vezes esquecem esta convenção e, por exemplo, definem o nome do arquivo de acordo com a tarefa: Lab6.java. Exemplo errado: nome do arquivoLab6.java
public class Airplane extends Vehicle
  Seat pilot;
  public Airplane() {
    pilot = new Seat();
  }
}
Exemplo corrigido: nome do arquivoAirplane.java
public class Airplane extends Vehicle
  Seat pilot;
  public Airplane() {
    pilot = new Seat();
  }
}
Observe:presume-se que o nome da classe comece com uma letra maiúscula. Sistemas operacionais que diferenciam maiúsculas de minúsculas em nomes de arquivos podem apresentar problemas adicionais, especialmente para estudantes que estão aprendendo Java em Unix e que estão acostumados com o sistema de nomenclatura de arquivos DOS. A classe MotorVehicledeve ser armazenada em um arquivo MotorVehicle.java, mas não em um arquivo motorvehicle.java.

2. Comparação usando==

Em Java, strings são objetos da classe java.lang.String. O operador ==aplicado aos objetos verifica a igualdade das referências aos objetos! Às vezes os alunos não entendem a semântica do operador ==e tentam usá-lo para comparar strings. Exemplo errado:
// проверим, equals ли первый аргумент "-a"
if (args[0] == "-a") {
    optionsAll = true;
}
A maneira correta de comparar 2 strings quanto à igualdade é usar o método equals()de classe java.lang.String. Ele retorna truese as strings tiverem o mesmo comprimento e contiverem os mesmos caracteres. (Nota: na verdade isso não garante igualdade. Na verdade, equalsverifica se 2 strings são iguais caractere por caractere) Exemplo corrigido:
//  проверим, equals ли первый аргумент "-a"
if ("-a".equals(args[0])) {
    optionsAll = true;
}
Esse erro é estúpido, porque na verdade o código Java acaba sendo sintaticamente correto, mas no final não funciona conforme o esperado. Alguns alunos também tentam usar operadores de comparação >e em vez de <=métodos compareTo()de classe java.lang.String. Este erro é mais fácil de detectar porque causa erros na fase de compilação.

3. Esqueci de inicializar objetos que são elementos do array.

Em Java, um array de objetos é na verdade um array de referências de objetos. Criar um array é simplesmente criar um conjunto de referências que não apontam para nada (ou seja, são nulas). Para realmente criar um array "completo" de objetos, você precisa inicializar cada elemento do array. Muitos estudantes não entendem isso; eles acreditam que, ao criar um conjunto de objetos, eles próprios criam automaticamente os objetos. (Na maioria dos casos, os alunos trazem esse conceito do C++, onde a criação de uma matriz de objetos resulta na criação dos próprios objetos chamando seu construtor padrão.) No exemplo abaixo, o aluno deseja criar 3 objetos da classe StringBuffer. O código será compilado sem erros, mas ocorrerá uma exceção na última linha NullPointerException, onde um objeto inexistente é acessado. Exemplo errado:
// Создаем массив из StringBuffer
StringBuffer [] myTempBuffers;
myTempBuffers = new StringBuffer[3];
myTempBuffers[0].add(data);
Para evitar esse erro, você deve se lembrar de inicializar os elementos do array. Exemplo corrigido:
// Создаем массив из StringBuffer и инициализируем элементы
StringBuffer [] myTempBuffers;
myTempBuffers = new StringBuffer[3];
for (int ix = 0; ix < myTempBuffers.length; ix++)
     myTempBuffers[ix] = new StringBuffer();

myTempBuffers[0].add(data);

4. Colocando várias classes com um modificador em um arquivo de uma só vezpublic

Os arquivos de origem Java estão associados de certas maneiras às classes contidas nesses arquivos. O relacionamento pode ser caracterizado da seguinte forma: Qualquer classe Java é armazenada em no máximo um arquivo. Em qualquer arquivo de código-fonte você não pode colocar mais de 1 classe com o modificador public. Se houver uma classe com um modificador no arquivo de código-fonte public, o nome do arquivo e o nome da classe devem ser estritamente iguais (nota de tradução: até o caso, ver ponto 1) Às vezes, os alunos esquecem a 2ª regra, o que leva a erros na compilação de palco. A mensagem de erro para a 2ª e 3ª regras será a mesma (que é o que realmente dificulta o reconhecimento deste erro).

5. Substituição de um campo de classe por uma variável local.

Java permite declarar variáveis ​​​​dentro de um método cujo nome corresponde aos campos da classe. Neste caso, as variáveis ​​locais terão precedência e serão utilizadas no lugar dos campos. O compilador gerará um erro se variáveis ​​com os mesmos nomes forem de tipos diferentes. Se forem do mesmo tipo, não haverá erro de compilação e os motivos do funcionamento incorreto do programa não serão claros. Exemplo errado:
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;
    }
}
Existem várias maneiras de corrigir esse erro. A mais simples é acessar os campos da classe usando um ponteiro implícito this: this.Name_поля. A melhor forma é renomear o campo da classe ou variável local, assim a substituição não ocorrerá. (aprox. trad.: O 2º método não é o nosso método. Além disso, não garante que algum dia não substituirei acidentalmente um campo de uma variável. Uma dificuldade ainda maior surge com a herança, quando não vejo quais campos a classe tem) Exemplo corrigido:
// 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;
  }
Outro local possível para esse erro ocorrer é definir o nome do parâmetro do método como igual ao nome do campo da classe. Isso fica bem em construtores, mas não é adequado para métodos normais.

Aproximadamente. tradução

um pouco caótico, mas essa é a essência

public class Test {
   private int param = 0;

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

isto é, tudo fica lindo no construtor, mas isso não deve ser usado para métodos comuns.

6. Esqueci de chamar o construtor pai (superclasse)

Quando uma classe estende outra classe, cada construtor de subclasse deve chamar algum construtor de superclasse. Isso geralmente é conseguido chamando o construtor da superclasse com o método super(x)colocado na primeira linha do construtor. Se não houver chamada na primeira linha do construtor super(x), o próprio compilador insere esta chamada, mas sem parâmetros super():. (trad. aprox.: x...se, mas eu não sabia) Às vezes os alunos esquecem desse requisito. Normalmente isso não é um problema: a chamada ao construtor da superclasse é inserida pelo compilador e tudo funciona bem. No entanto, se a superclasse não tiver um construtor padrão, o compilador gerará um erro. No exemplo abaixo, todos os construtores de superclasse java.io.Filepossuem 1 ou 2 parâmetros: Exemplo errôneo:
public class JavaClassFile extends File {
    String classname;
    public JavaClassFile(String cl) {
        classname = cl;
    }
}
A solução para o problema é inserir uma chamada explícita ao construtor da superclasse correto: Exemplo corrigido:
public class JavaClassFile extends File {
    String classname;
    public JavaClassFile(String cl) {
        super(cl + ".class");
        classname = cl;
    }
}
Uma situação mais desagradável ocorre quando a superclasse possui um construtor padrão, mas não inicializa totalmente o objeto. Nesse caso, o código será compilado, mas a saída do programa pode estar incorreta ou pode ocorrer uma exceção.

7. Captura incorreta de exceções

O sistema de tratamento de exceções do Java é bastante poderoso, mas difícil de entender para iniciantes. Os alunos proficientes em C++ ou Ada geralmente não têm as mesmas dificuldades que os programadores C e Fortran. Os exemplos abaixo mostram alguns erros comuns. Neste exemplo, a exceção não é nomeada. O compilador indicará esse erro no estágio de compilação, por isso é fácil corrigi-lo sozinho. Exemplo errado:
try {
    stream1 = new FileInputStream("data.txt");
} catch (IOException) {
    message("Could not open data.txt");
}
Exemplo corrigido:
try {
   stream1 = new FileInputStream("data.txt");
} catch (IOException ie) {
   message("Could not open data.txt: " + ie);
}
A ordem dos blocos catchdetermina a ordem em que as exceções são capturadas. Deve-se levar em consideração que cada bloco capturará todas as exceções da classe especificada ou de qualquer uma de suas subclasses. Se você não levar isso em consideração, poderá acabar com um bloco catch inacessível, que o compilador apontará. No exemplo abaixo SocketExceptionhá uma subclasse de IOException. Exemplo errado:
try {
    serviceSocket.setSoTimeout(1000);
    newsock = serviceSocket.accept();
} catch (IOException ie) {
    message("Error accepting connection.");
} catch (SocketException se) {
    message("Error setting time-out.");
}
Exemplo corrigido:
try {
    serviceSocket.setSoTimeout(1000);
    newsock = serviceSocket.accept();
} catch (SocketException se) {
    message("Error setting time-out.");
} catch (IOException ie) {
    message("Error accepting connection.");
}
Se for possível ocorrer uma exceção em seu código que não seja capturada por nenhum bloco try-catch, então essa exceção deverá ser declarada no cabeçalho do método. RuntimeException( Isso não é necessário para exceções – subclasses de uma classe ). Às vezes, os alunos esquecem que chamar um método pode gerar uma exceção. A maneira mais fácil de corrigir isso é colocar a chamada do método em um bloco try-catch. Exemplo errado:
public void waitFor(int sec) {
    Thread.sleep(sec * 1000);
}
Exemplo corrigido:
public void waitFor(int sec) throws InterruptedException {
    Thread.sleep(sec * 1000);
}

8. O método de acesso tem um tipovoid

Este é um erro muito simples. O aluno cria um método para acessar uma variável, mas especifica que o método não retorna nada (coloca um modificador voidno cabeçalho do método). Para corrigir esse erro, você deve especificar o tipo de retorno correto. Exemplo errado:
public class Line {
    private Point start, end;
    public void getStart() {
      return start;
    }
}
Exemplo corrigido:
public class Line {
    private Point start, end;
    public Point getStart() {
      return start;
    }
}
Especificar o tipo de retorno errado gera toda uma classe de erros. Normalmente, o compilador reconhecerá esses erros e os reportará para que os próprios alunos possam corrigi-los. Autor: A. Grasoff™ Leia a continuação Link para a fonte: Erros de programadores java iniciantes
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION