¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. Aprender la Programación Orientada a Objetos con el lenguaje Java
  3. Los tipos en Java
Extrait - Aprender la Programación Orientada a Objetos con el lenguaje Java (con ejercicios prácticos y corregidos)
Extractos del libro
Aprender la Programación Orientada a Objetos con el lenguaje Java (con ejercicios prácticos y corregidos) Volver a la página de compra del libro

Los tipos en Java

Introducción

Recodemos que todo programa utiliza variables. La variable es un contenedor de memoria donde se almacena información. El programa lee o escribe en sus variables según sus operaciones. La naturaleza de la variable condiciona la información que puede contener. Por ejemplo, una variable de tipo sencillo puede contener una información «booleana» 1 o 0 para sí o no. Una variable más compleja puede definir una persona con varios «atributos», a su vez de tipos diferentes (cadenas de caracteres, fechas, valores digitales, etc.). Con Java (como sucede con C, C++ o C#), una variable se debe declarar con un tipo que conservará durante todo su ciclo de vida en el interior de la aplicación. La variable también debe tener un nombre. El compilador comprueba sus instrucciones en función del tipo de las variables implicadas y devuelve error si intenta hacer operaciones imposibles, como escribir información de una persona en una variable booleana...

En Java, la noción de variable normalmente está muy relacionada con las instancias de objetos, principalmente con sus «campos» o «estados» (atributos en sentido UML). Las variables también se intercambian durante las llamadas a los métodos e incluso se crean temporalmente para las necesidades de estas operaciones.

Hay dos tipos de variables:

  • los tipos primitivos,

  • los tipos por referencia....

Los tipos primitivos

A los tipos primitivos solo les falta la etiqueta 100 % Objeto para Java. Son «justo» contenedores de tamaños específicos que almacenan los valores «primitivos» y no tienen métodos. Los tipos «primitivos» incluyen los ocho tipos básicos presentes en la siguiente tabla:

Tipo

Tamaño en bits

Gama de valores

boolean

Depende del sistema

true o false

char

16 bits

0 a 65535

byte

8 bits

-128 a 127

short

16 bits

-32768 a 32767

int

32 bits

-2^31 a 2^31-1

long

64 bits

-2^63 a 2^63-1

float

32 bits

-3.40282347E+38 a 3.40282347E+38

double

64 bits

-1.79769313486231570E+308 a 1.79769313486231570E+308

Más adelante vamos a ver que todos los objetos heredan de la misma clase raíz java.lang.Object. Esta herencia implícita puede ser muy práctica porque ofrece al desarrollador un juego de métodos básico común a todas las instancias de objetos. Como es una lástima que los tipos primitivos no tengan esta funcionalidad, Java nos ofrece las clases llamadas wrappers, que encapsulan cada tipo primitivo. Estas clases forman parte del paquete java.lang y encontrar sus nombres es muy sencillo: la mayor parte de las veces, es suficiente con tomar el tipo primitivo y pasar su primera letra a mayúsculas. De esta manera, se encapsula el tipo primitivo boolean en una clase Boolean. Sin embargo, el tipo int se encapsula por Integer.

Vamos a estudiar...

Los tipos por referencia

Al contrario de lo que sucede con los tipos primitivos, los tipos por referencia almacenan las referencias a los datos. Estos datos se escriben en una zona de memoria llamada heap (pila). Es accesible desde otras instancias de clase. Su ciclo de vida termina cuando no se necesiten más. Mientras exista al menos una referencia activa en la zona de datos, esta se mantendrá. Tan pronto como no haya más referencias, la zona se considera no utilizada y se procede a su destrucción por parte del garbage collector.

Un tipo por referencia puede no referenciar a nada (o no todavía). En este caso, permanece como null.

La instanciación de una clase se realiza únicamente con la palabra clave new.

Una variable de tipo por referencia caracteriza una instancia de clase; a saber, la dirección donde está el objeto. Como habíamos visto, el objeto mezcla atributos y métodos y, por lo tanto, incluye datos más complejos que aquellos contenidos por los tipos primitivos.

Tendremos la ocasión de volver sobre este tema de las referencias y profundizar echando un vistazo a algunas reglas básicas.

Una variable de tipo por referencia contiene la dirección de un objeto. Mientras el objeto no se asigne explícitamente en su programa, es decir, que el sistema operativo no le asigne una fracción de memoria a su tamaño, la variable contiene null.

Durante una operación...

Para ayudarnos...

Durante este paseo iniciático en el dominio de la POO, vamos a construir pequeñas aplicaciones de prueba en modo consola. Usando la programación, vamos a comprobar determinada información y visualizar mensajes en la ventana de salida Output de IntelliJ IDEA.

En lenguaje Java, la palabra clave assert permite comprobar si una condición es verdadera durante la ejecución de su código. Utilizando este método, no interviene sobre el desarrollo del programa propiamente dicho; comprueba que lo que está previsto en un determinado lugar del código es cierto. Si la condición es falsa, se mostrará un mensaje de error para informarle de esto.

Un assert no es una operación condicional que deriva el flujo hacia uno u otro subprograma. Cuando un assert se «despierta», debería ponerle sobre la pista de un defecto (bug) en su programa.

Sintaxis de utilización de la palabra clave assert

assert( <condición> ); 

Ejemplo de utilización de la palabra clave assert

Para comprobar la utilización de la palabra clave assert, vamos a retomar el proyecto HelloWorld y añadirle algunas líneas.

    public static void main(String[] args) {  
       // El fragmento obligado...  
       System.out.println("Hello World");  
  
 ...

La superclase java.lang.Object

La clase Object es la clase «raíz» (clase de base) de las clases Java existentes y de las clases que va a crear (la noción de herencia ya se ha abordado un poco en los primeros capítulos). La herencia de Object es implícita y, por lo tanto, su declaración es inútil. Todas las clases heredan de sus métodos y la idea es sustituirlas adaptándolas a la lógica de la clase que va a desarrollar. Por ejemplo, en la clase Object, existe un método toString que devuelve una cadena «que representa al objeto». El hecho de implementar este método en su clase va a «desconectar» el de la clase de base y le va a permitir reenviar una cadena que describa su objeto en la forma que quiera. Por ejemplo, si su aplicación administra una lista de objetos de tipo Persona, entonces puede construir en el método toString una cadena que retoma los atributos principales de cada instancia, como el nombre, el identificador, etc., y llamará este método durante las fases de puesta a punto para visualizar la información en la ventana Consola.

Vemos los métodos de java.lang.Object que vamos a poder sustituir o utilizar en nuestras propias clases.

1. equals

public boolean equals(Object o); 

El funcionamiento básico de este método (por lo tanto, el comportamiento ejecutado si no lo redefine en su clase) es análogo al del operador ==. Por lo tanto, «en la parte inferior», la prueba más básica es la comparación de las referencias (finalmente las direcciones) de los dos objetos. Para comprobarlo, vamos a poner en acción la palabra clave assert.

       // Creación de una variable por referencia llamada pr1  
       // sobre un objeto de tipo PruebaReferencia  
       PruebaReferencia pr1; // por el momento pr1 vale null  
       // Asignación de un objeto y almacenamiento de su dirección 
       // en la variable pr1  
       pr1 = new PruebaReferencia();  
  
       // Creación de una variable por referencia llamada pr2  
       // en un objeto de tipo PruebaReferencia   
     ...

La clase java.lang.String

Existe una clase muy «integrada» en la gramática Java: la class String (que forma parte del paquete java.lang).

Esta clase encapsula una colección de caracteres Unicode, encapsulados a su vez por el tipo java.lang.Character. String es de tipo por referencia (por lo tanto, asignado en el heap), pero por razones de comodidad el uso del operador new para instanciarlo no es el método más utilizado. En efecto, es suficiente con asignar una cadena durante la declaración de un objeto String para instanciarlo.

String s = "Viva la programación JAVA:)"; 

La cadena literal se puede construir.

String hello = "Hola, estamos en el "   
           + Calendar.getInstance().get(Calendar.DAY_OF_YEAR)  
           + "° día del año";  
  
System.out.print(hello); 

A continuación se muestra la salida por la consola correspondiente al 14 de enero:

Hola, estamos en el 14° día del año 

Durante la declaración de la cadena literal, el carácter \ (antislash) se toma por defecto como secuencia de escape.

Por ejemplo, \r\n significa «retorno de carro» y «nueva línea»; por lo tanto, concretamente un salto de línea en la visualización de la cadena.

En consecuencia, si la cadena literal contiene \ «reales»...

Ejercicio

1. Enunciado

Cree una aplicación de tipo Consola, que servirá de soporte para las siguientes preguntas.

 Cree una variable de tipo int llamada i, cuyo valor sea 10.

 Cree una variable de tipo java.lang.Integer llamada j, cuyo valor sea el contenido de i.

 Cree una variable de tipo java.lang.Integer llamada k, cuyo valor sea el contenido de i.

 Muestre i, j y k.

 Añada 1 a i.

 Muestre i, j y k.

 Verifique con un assert que Integer es de tipo Object.

  Muestre los hashcode de j y de k.

2. Corrección

 Seleccione el menú File y, a continuación, la opción New Project....

 Conserve las opciones por defecto y haga clic en Next.

 Marque Create project from template de tipo CommandeLine App.

 Llame a su proyecto LabTypesJava, elija un directorio de trabajo que termine por un subdirectorio llamado LabTypesJava y a continuación, indique com.eni como Base package.

 Haga clic en Finish.

El contenido del archivo fuente generado por el asistente es el siguiente:

package com.eni;   
  
public class Main {   
  
    public static void main(String[] args) {   
    // write your code here   
    }   
} 

El método main es el punto de entrada del programa y vamos a desarrollar nuestro código dentro. El método main puede...