Errores semánticos de Java | Por qué el programador de Java debe reconocer los errores semánticos

Mar 08 2023
Únase a JAVA FLAMES Muchas personas encuentran difícil de entender la diferencia entre errores semánticos y errores sintácticos (sintaxis) en código Java, pero son diferentes. Puede ver un error semántico cuando la sintaxis de su código es correcta pero el uso del código no es correcto.

Únete a JAVA FLAMES

Muchas personas encuentran difícil de entender la diferencia entre los errores semánticos y los errores sintácticos (sintaxis) en el código Java, pero son diferentes. Puede ver un error semántico cuando la sintaxis de su código es correcta pero el uso del código no es correcto.

· ¿ Qué es un error semántico?
· ¿ Cómo se detectan los errores semánticos?
· Errores semánticos comunes

¿Qué es un error semántico?

Un error semántico es un problema en su código que impide que el intérprete lo entienda. Puede que no haya ningún problema con la lógica que ha escrito, pero hará que el programa se bloquee de la forma en que lo ha escrito. Por ejemplo, el siguiente código producirá un resultado incorrecto en un error de tiempo de ejecución semántico:

var a = 1 // No error
var b = 2 // No error
var c = 3 // No error
a + c = b

Los errores semánticos se detectan en el momento de la compilación y puede pensar en ellos como errores de análisis estático. Por ejemplo , si intenta ejecutar una variable que no ha declarado, arrojará un error semántico: un error semántico ocurre cuando un programador escribe código que no logra comunicar su propósito previsto. Esto es diferente de un error de sintaxis, que ocurre cuando el código es sintácticamente correcto pero no realiza la tarea diseñada.

En otras palabras, un error semántico se refiere a un programa incorrecto que produce un resultado que no tiene sentido. Por ejemplo , si una aplicación meteorológica dice "Cálido y soleado" incluso cuando afuera está lloviendo, esto sería un error semántico. El programa no produjo lo que se suponía que debía producir.

¿Cómo se detectan los errores semánticos?

el compilador detecta algunos de los errores semánticos (los errores semánticos estáticos), lo que genera un mensaje que indica el tipo de error y la posición en el archivo fuente de Java donde ocurrió el error (observe que el error real podría haber ocurrido antes de la posición señalado por el compilador).

En este punto, hemos descrito errores semánticos estáticos . En cada caso, el compilador marca un error semántico estático cuando no se cumple un requisito del lenguaje de programación (tipos no válidos).

Hay otro tipo de problema: ¿qué pasa si tu programa compila y ejecuta, pero no hace lo que querías que hiciera? La computadora está haciendo exactamente lo que usted programó, pero lo que programó estuvo mal. Este es otro tipo de error semántico: cuando el programador utiliza incorrectamente el lenguaje de programación para resolver el problema.

A diferencia de un error semántico estático, un error semántico dinámico tiene que ver con el significado. Si un programa contiene este tipo de error, se ejecutará con éxito, pero no generará el resultado correcto.

La depuración no es tan fácil con un error semántico. Veamos un ejemplo.

/**
 * This program prints the total benefit for the company
 * 
*/
public class TotalBenefit {
 public static void main(String[] args) {
  int branch1 = 250; 
        int branch2 = 500;
        System.out.println("The total benefit is  $" + (branch1 * branch2));
 }
}

Errores semánticos comunes

Error de tipos incompatibles

Este error de sintaxis es muy común entre los principiantes. En lenguajes de programación compilados como Java, solo puede asignar valores a variables compatibles.

Compatible significa que tienen el mismo tipo o tienen tipos que el compilador puede convertir automáticamente.

En el siguiente ejemplo, puede ver que en Java no puede asignar un doble a una variable entera. Algunos lenguajes de programación pueden realizar la conversión automáticamente, pero si ve el error a continuación, la solución es simple. Simplemente cambie el tipo de la variable 'a', o asigne un valor entero en lugar de uno doble (5.5).

Este tipo de error semántico puede ser complicado porque el compilador marcará algunos errores y no otros. Por ejemplo, si intenta asignar un flotante a una variable int, el compilador muestra un mensaje de error.

Por otro lado, si asigna un int a una variable flotante, el compilador realiza una conversión de tipo automática al int para convertirlo en flotante. El problema con este segundo escenario es que puede introducir errores silenciosamente en su código, especialmente si realmente quiso usar un flotante.

"Es posible que la variable <X> no se haya inicializado"

Esto ocurre cuando una variable local declarada dentro de un método no ha sido inicializada. Puede ocurrir cuando una variable sin un valor inicial es parte de una instrucción if.

int x;
if (condition) {
  x = 5;
}
System.out.println(x); // x may not have been initialized

Es posible convertir entre muchos tipos diferentes en Java. Sin embargo, no importa cuánto le gustaría convertir un valor booleano en un int, Java no le permitirá hacerlo. El concepto de realizar la conversión es sintácticamente correcto, pero lo estás aplicando incorrectamente, lo que hace que esto sea un error semántico que el compilador siempre detecta.

El error de "tipos inconvertibles" ocurre cuando el código Java intenta realizar una conversión ilegal.

TypeInvocationConversionTest.java:12: inconvertible types
found   : java.util.ArrayList<java.lang.Class<? extends TypeInvocationConversionTest.Interface1>>
required: java.util.ArrayList<java.lang.Class<?>>
lessRestrictiveClassList = (ArrayList<Class<?>>) classList;
                                                 ^

“variable no estática. . . no puede ser referenciado desde un contexto estático”

Este error ocurre cuando el compilador intenta acceder a variables no estáticas desde un método estático

public class StaticTest {
private int count=0;
   public static void main(String args[]) throws IOException {
       count++; //compiler error: non-static variable count cannot be referenced from a static context
   }
}

  • Declare la variable como estática en la firma.
  • Compruebe el código, ya que puede crear una instancia de un objeto no estático en el método estático.

Este problema ocurre cuando el código Java intenta llamar a un método no estático en una clase no estática. Aquí hay un ejemplo:

class Sample {
  private int age;
  public void setAge(int a) {
    age=a;
  }
  public int getAge() {
    return age;
  }
  public static void main(String args[]) {
    System.out.println(“Age is:”+ getAge());
   }
  }

Exception in thread “main” java.lang.Error: Unresolved compilation problem:
Cannot make a static reference to the non–static method getAge() from the type Sample

Obtendrá el mensaje "(arreglo) <X> no inicializado" cuando se haya declarado un arreglo pero no se haya inicializado. Las matrices tienen una longitud fija, por lo que cada matriz debe inicializarse con la longitud deseada.

El siguiente código es aceptable:

AClass[] array = {object1, object2}
  As is:
       AClass[] array = new AClass[2];
       …
       array[0] = object1;
       array[1] = object2;
  But not:
       AClass[] array;
       …
       array = {object1, object2};

Este problema ocurre cuando los operadores se usan para tipos, no en su definición.

Los operadores solo se definen para ciertos tipos, aunque se permite la conversión implícita de tipos entre ciertos tipos numéricos:

int a = 5; 
boolean b = true;
int c = a + b; // Error, can't add a boolean value double 
d = a + 1.4;  // OK, int is implicitly converted to double

Esto sucede a menudo cuando el código Java intenta usar una cadena de tipo en un cálculo. Para solucionarlo, la cadena debe convertirse en un número entero o flotante.

Posible pérdida de precisión

A veces se puede aplicar la fundición de forma incorrecta. Por ejemplo, convertir un flotante en un int funciona bien, pero con la pérdida de la parte decimal del número.

La “posible pérdida de precisión” ocurre cuando se asigna más información a una variable de la que puede contener. Si esto sucede, las piezas serán desechadas. Si esto está bien, entonces el código debe declarar explícitamente la variable como un nuevo tipo.

Este error surge cuando se intenta asignar un valor de mayor precisión a una variable de menor precisión sin un type cast explícito. Sorprendentemente, tal vez, los literales de punto flotante son de tipo doubley obtendrá este mensaje si intenta asignar uno a una variable de tipo float:

float sum = 0.0;  // Error, literal is not of type float

float sum = 0.0f;   // OK float sum = (float) 0.0;  // OK

Esta pérdida de precisión puede afectar la salida de su aplicación de formas inesperadas y hacer que la salida refleje un valor diferente al que esperaba. El compilador nunca encuentra este tipo de error porque ha aplicado específicamente una conversión a la variable y el compilador espera que sepa lo que está haciendo.

Aplicar el alcance incorrectamente

Cualquier variable que declare dentro de un método tiene el mismo alcance (visibilidad a otras partes de la aplicación, en otras palabras) que el método. En consecuencia, no puede declarar una variable int estática privada dentro de un método. En su lugar, debe definir la variable globalmente de esta manera:

public class PrivateVar
{
   // This declaration works.
   private static int PrivateInt = 3;
   public static void main(String[] args)
   {
      // This declaration doesn’t work.
      private static int PrivateInt = 3;
   }
}

Aquí hay algunos otros casos generales de errores semánticos en Java

Discrepancias de tipo : hay muchas maneras de usar el tipo incorrecto en C#. El ejemplo anterior es una forma. Aquí hay algunas otras formas posibles:

  • Pasar el tipo incorrecto de valor a un método.
  • Devolver el tipo incorrecto de valor de un método.
  • Establecer el tipo incorrecto de valor en una propiedad.
  • Establecer el tipo incorrecto de valor en un campo.
  • Establecer el tipo de valor incorrecto en una variable local.
  • Usar un tipo en una lista de argumentos genéricos que no se ajusta a las restricciones de tipo genérico.
  • Pasar el número incorrecto de argumentos a una llamada de método.
  • Pasar el número incorrecto de índices a una matriz o indexador.
  • Usar el número incorrecto de argumentos de tipo genérico para un tipo o método genérico.
  • Uso de nombres indefinidos: uso de un espacio de nombres, tipo, método, campo, variable o nombre de propiedad que no existe.
  • Definición de dos tipos en el mismo espacio de nombres con el mismo nombre
  • Definición de dos métodos en la misma clase con la misma lista de argumentos y nombre.
  • Definición de una propiedad, campo o tipo anidado que tiene el mismo nombre que otra propiedad, campo o tipo anidado en el mismo tipo propietario.
  • Definición de dos variables locales en ámbitos iguales o descendientes con los mismos nombres.

Apoya nuestra publicación siguiéndola

Spring 3.0 y sus funciones Pregunta de entrevista más frecuente basada en secuencias de Java8: semáforo de la parte final | API concurrente de Java Cómo ChatGPT transformará el SEO: ventajas y desafíos Qué causa los errores de sintaxis y cómo evitarlos| Cómo el compilador de Java detecta errores de sintaxis … La guía completa para construir una plataforma ICO de marca blanca Como un extraño me ayudó a comprender la triste verdad de la comunicación moderna La revolución de la IA: ¿Será la IA el único autor en ¿Medio? No vi que era uno de los mejores escritores en Medium RestTemplate | fingircliente | Cliente web con Spring Boot Cómo crear un proyecto simple de Quarkus con codificación de integración de base de datos: aplanar una matriz en Javascript Automatización del marketing en redes sociales con ChatGPT 10 widgets que todo desarrollador de Flutter debe dominar Revolucione su estudio con Active Recall: el método probado para retener información para...