Tema 33. Lenguaje de Programación Java

En Java, existen tres tipos principales de comentarios que se utilizan para documentar el código, cada uno con una sintaxis y propósito específicos:

  • Comentarios de una línea: Se utilizan para añadir breves notas o explicaciones en una sola línea. Comienzan con una doble barra inclinada (//).
    • Ejemplo: // Esto es un comentario de una línea.
  • Comentarios de varias líneas: Permiten escribir bloques de texto extensos que ocupan más de una línea. Se inician con /* y finalizan con */.
    • Ejemplo: /* Este es un ejemplo de un comentario que ocupa varias líneas */
  • Comentarios de Javadoc: Son un tipo especial de comentario multilínea que se utiliza para generar documentación técnica automática en formato HTML. Comienzan con /** y terminan con */. Dentro de estos, se suelen incluir etiquetas específicas como:
    • @author: Para indicar el autor del código.
    • @version: Para especificar la versión del software.
    • @param: Para describir los parámetros de un método.
    • @return: Para detallar el valor que devuelve un método.

Los tipos de datos se clasifican fundamentalmente en dos categorías: tipos primitivos y tipos referencia.  

1. Tipos de Datos Primitivos

Representan valores sencillos con funcionalidad integrada y no son objetos. Java ofrece clases «envolventes» (wrappers) para tratarlos como tales cuando sea necesario.  

  • Enteros:
    • byte: 8 bits, rango de -128 a 127.  
    • short: 16 bits, rango de -32.768 a 32.767.  
    • int: 32 bits, rango aproximado de ±2 mil millones.  
    • long: 64 bits, para valores numéricos muy grandes.  
  • Punto flotante (Reales):
    • float: 32 bits, para precisión simple.  
    • double: 64 bits, para precisión doble.  
  • Otros:
    • boolean: Representa valores true o false.  
    • char: 16 bits, utiliza el estándar Unicode para caracteres.  
2. Tipos de Datos Compuestos (Referencia)

Incluyen objetos y estructuras más complejas que se pasan «por referencia».  

  • String: Cadena de caracteres. Es una clase y se puede instanciar con new o directamente con comillas dobles.  
  • Arrays: Colecciones de elementos del mismo tipo. Se indexan desde 0 y su tamaño se define dinámicamente con new.  
  • Clases y Colecciones: Estructuras que agrupan atributos y métodos.  
3. Conversión de Tipos (Casting)

Java permite la promoción automática de tipos pequeños a grandes (ej. de int a double). Para conversiones inversas o específicas, se debe usar el casting o conversión explícita.  

  • Ejemplo de casting: int i = (int) f; (donde f es un float).  
  • Conversión de String a número: Se usan métodos como Integer.parseInt() o Float.parseFloat().  
Detalles Importantes
  • Valores por defecto: Las variables de clase no inicializadas toman valores automáticos (0 para números, false para booleanos, carácter nulo para char).  
  • Variables locales: Deben inicializarse siempre explícitamente antes de su uso para evitar errores de compilación.  
  • Constantes: Se declaran utilizando la palabra reservada final antes del tipo de dato
Separadores

En Java existen seis separadores distintos. A continuación se muestra el uso de cada uno de ellos.

  • Los paréntesis ():
    • Delimitan listas de parámetros. Modifican la precedencia de una expresión. Delimitan condiciones. Indican el tipo en las coerciones.
  • Las llaves {}:
    • Definen bloques de código. Delimitan las listas de valores iniciales de los arrays.
  • Los corchetes []:
    • Declaran arrays y permiten acceder a sus elementos.
  • El punto y coma «;»:
    • Terminan instrucciones.
  • La coma «,»:
    • Separan identificadores en declaraciones. Encadenan expresiones.
  • El punto «.»:
    • Acceden a los atributos y métodos de una clase. Acceden a un subpaquete de un paquete. Operadores
Modificadores de acceso

los modificadores de acceso son fundamentales para el encapsulamiento en Java, ya que definen desde qué partes del código se puede acceder a los atributos y métodos de una clase.  

Aquí tienes el detalle de los tres modificadores que mencionas:

1. Public (Público)
  • Alcance: Es el nivel de acceso más permisivo.  
  • Visibilidad: Un elemento declarado como public es accesible desde cualquier otra clase, sin importar si pertenece al mismo paquete o a uno diferente.  
  • Uso común: Se utiliza para los métodos que forman la interfaz de la clase (lo que queremos que otros usen) y para las constantes.
2. Protected (Protegido)
  • Alcance: Intermedio.
  • Visibilidad: Es accesible por:
    1. Cualquier clase que esté en el mismo paquete.  
    2. Cualquier subclase (clases que heredan de ella), incluso si estas subclases están en paquetes diferentes.
  • Uso común: Se usa en la herencia para permitir que las clases hijas puedan manipular directamente ciertos atributos o métodos de la clase padre.  
3. Private (Privado)
  • Alcance: El más restrictivo.  
  • Visibilidad: Solo es accesible dentro de la propia clase donde se ha declarado. Ninguna otra clase (ni siquiera las subclases o clases del mismo paquete) puede verlo o modificarlo directamente.  
  • Uso común: Es el estándar para los atributos (variables de instancia) siguiendo el principio de ocultación de datos. Para acceder a ellos desde fuera, se suelen usar métodos públicos getters y setters.  

Nota adicional: El acceso por defecto (Default / Package-private)

Aunque no lo mencionas específicamente, implica que si no escribes ningún modificador, Java aplica el acceso por defecto. En este caso, el elemento solo es visible para las clases que están dentro del mismo paquete, pero no para las subclases que estén en paquetes distintos.  

Vamos a profundizar en la Programación Orientada a Objetos (POO) y el Manejo de Excepciones, que son los siguientes bloques fundamentales tras haber visto los tipos de datos y estructuras.

Aquí tienes una propuesta de por dónde podemos seguir:

1. Manejo y Relaciones entre Clases

Podemos ver cómo Java organiza el código más allá de las variables:

  • Constructores: Cómo se crean los objetos y el uso de new.
  • El concepto de this: Para referenciar al objeto actual.
  • Herencia (extends): Cómo una clase hereda atributos y métodos de otra.
  • Polimorfismo: La capacidad de un objeto de tomar diferentes formas. Clase Abstract o Interface.
2. Tratamiento de Excepciones

Es una parte crucial del documento para crear programas robustos. Veríamos:

  • El bloque try-catch-finally.
  • La diferencia entre excepciones comprobadas (checked) y no comprobadas (unchecked).
  • Cómo lanzar tus propias excepciones con throw y throws.
3. Colecciones (Framework de Collections)

Si ya dominas los Arrays, lo siguiente es ver estructuras más flexibles:

  • List (como ArrayList o LinkedList).
  • Set (conjuntos de elementos únicos).
  • Map (diccionarios de clave-valor).
4. Manejo de Hilos (Threads)

Como vimos brevemente antes, el final del documento se centra en la concurrencia:

  • Cómo crear hilos implementando la interfaz Runnable o heredando de Thread.
  • Ciclo de vida completo del hilo (Nuevo, Ejecutable, Bloqueado, Muerto).
  • Sincronización para evitar errores cuando varios hilos acceden al mismo dato.

Para crear objetos en Java a partir de las clases, el documento detalla un proceso que se divide esencialmente en tres pasos clave: declaración, instanciación e inicialización.

Aquí tienes el detalle de cómo se crean según el texto:

El operador new

La creación de un objeto siempre requiere el uso de la palabra reservada new. Este operador es el encargado de reservar espacio en la memoria para el nuevo objeto.

El Constructor

Cuando utilizas new, Java llama automáticamente a un método especial de la clase llamado Constructor.

  • Función: Su objetivo es inicializar los atributos del objeto.
  • Nombre: El constructor debe llamarse exactamente igual que la clase.
  • Sin tipo de retorno: A diferencia de los métodos normales, el constructor no devuelve nada (ni siquiera void).
Ejemplo de creación (Sintaxis)

Si tenemos una clase llamada Punto, la creación se vería así:

Referencias y el punto (.)

Una vez creado el objeto, la variable (en este caso miPunto) no contiene el objeto en sí, sino una referencia (una dirección de memoria) hacia donde está el objeto.

  • Para acceder a sus «miembros» (atributos o métodos), se utiliza el operador punto.
  • Ejemplo: miPunto.x = 20; o miPunto.dibujar();.
El uso de this

Dentro de la clase, cuando estás definiendo cómo se crea el objeto, se suele usar la palabra this y sirve para que el objeto se refiera a sí mismo. Es muy útil en los constructores para diferenciar entre el nombre de un atributo y el nombre de un parámetro:

Colecciones en Java

Las colecciones en Java son tipos de datos compuestos (clases) diseñados para agrupar y gestionar múltiples objetos de forma eficiente. A diferencia de los arrays, cuyo tamaño es estático, el framework de colecciones ofrece estructuras dinámicas que facilitan la organización, búsqueda y manipulación de datos.  

Aquí tienes las interfaces y estructuras principales detalladas en el documento:

Interfaz List (Listas)

Representa una colección ordenada de elementos que permite duplicados. Cada elemento tiene una posición específica basada en un índice (empezando desde 0).  

  • ArrayList: Es la implementación más común. Funciona como un array dinámico que crece automáticamente según se necesite.  
  • LinkedList: Ideal si realizas muchas inserciones o eliminaciones frecuentes en medio de la lista, ya que sus elementos están enlazados entre sí.
Interfaz Set (Conjuntos)

Se utiliza para colecciones que no permiten elementos duplicados. Es la estructura ideal cuando necesitas asegurar la unicidad de los datos.  

  • HashSet: Almacena los elementos en una tabla hash. No garantiza ningún orden específico de los elementos.  
  • SortedSet / TreeSet: Mantiene los elementos ordenados automáticamente, ya sea por su orden natural o por un comparador específico.  
Interfaz Map (Mapas o Diccionarios)

A diferencia de las anteriores, los mapas almacenan parejas de clave-valor. Cada clave debe ser única y se utiliza para recuperar rápidamente su valor asociado.  

  • HashMap: Implementación basada en tabla hash para una búsqueda rápida de valores mediante claves.  
  • SortedMap / TreeMap: Mantiene las claves ordenadas de forma ascendente.  
Herramientas de Recorrido: Iteradores

Para recorrer cualquier colección de forma estandarizada, Java proporciona interfaces específicas:

  • Iterator: Permite recorrer una colección de principio a fin, obteniendo elementos y permitiendo eliminarlos de forma segura durante el recorrido.  
  • ListIterator: Es una versión más avanzada para listas que permite recorrer los elementos tanto hacia adelante como hacia atrás.  
Resumen de visibilidad y acceso

Recuerda que para trabajar con estas colecciones en tus clases, debes tener en cuenta los modificadores de acceso:

  • Es recomendable declarar las colecciones como private dentro de una clase para proteger los datos y acceder a ellas mediante métodos públicos o protegidos.  
  • Toda colección hereda métodos básicos de la clase raíz Object, como toString() para visualizar su contenido o equals() para compararlas.