Un tipo define una expresión o variable de manera que se puede predecir su comportamiento. Este capítulo trata todos los tipos principales de Java, mostrando cómo declarar variables, asignar valores y combinar tipos en expresiones. Identificadores Los identificadores se utilizan como nombres de clase, método y variable. Un identificador puede ser cualquier sentencia descriptiva de letras en mayúscula o minúscula , números y los caracteres subrayado (_) y signo de dólar ($). No se deban comenzar por número. Java diferencia entre mayúsculas/minúsculas, lo que significa que VALOR es un identificador diferente de Valor. Palabras clave reservadas Las palabras clave reservadas son identificadores especiales que el lenguaje Java se ha reservado para controlar cómo está definido su programa. Se utilizan para identificar los tipos, modificadores y mecanismos para control de secuencia incorporados. Estas palabras clave sólo se pueden utilizar para su propósito original y no se pueden utilizar como identificadores de nombres de variable, clase o método. Hay 59 palabras clave reservadas definidas en la versión Java 1.0, que se muestran en la siguiente tabla. Variables La variable es la unidad básica de almacenamiento en un programa en Java. Una variable se define mediante la combinación de un identificador, un tipo y un ámbito. Declaración de un variable La forma básica de una declaración de variable es: tipo identificador [ = valor ] [, identificador [ = valor ] ... ] ; El tipo puede ser: byte, short, int, long, char, float, double, boolean o el nombre de una clase o interfaz. Conceptos todos que describiremos más adelante. Ámbito de una variable Los bloques de sentencias compuestas en Java se delimitan con dos llaves { }. Las variables de Java sólo son válidas desde el punto donde están declaradas hasta el final de la sentencia compuesta que la engloba. Se pueden anidar estas sentencias compuestas y cada una puede contener su propio conjunto de declaraciones de variables locales. Sin embargo, no se puede declarar una variable con el mismo nombre que una de un ámbito superior. Tipos simples En Java, que es un lenguaje de programación orientado a objetos, se ha renunciado a la abstracción uniforme del concepto "todo es un objeto" por cuestiones de eficiencia. El rendimiento del sistema fue una meta fundamental en el desarrollo de Java. Esta decisión condujo a la creación de los tipos simples de Java. No están en absoluto orientados a objeto, y son análogos a los tipos simples de la mayoría de los otros lenguajes que no utilizan objetos. Los tipos simples representan expresiones atómicas, de un solo valor, como números enteros, de coma flotante, caracteres y valores booleanos. Java también tiene un tipo para matrices, que son conjuntos de tamaño fijo de un único tipo. También tiene los tipos compuestos, clases e interfaces que veremos en un próximo capítulo. Parte de la seguridad y robustez de Java viene del hecho de que Java es un lenguaje fuertemente tipado. Cada expresión tiene un tipo. Cada variable tiene un tipo y cada tipo está definido estrictamente. En todas las asignaciones de expresiones a variables, tanto explícitas como a través de paso de parámetros en llamadas a método, se comprueba la compatibilidad de los tipos. El compilador de Java comprueba estáticamente todo el código que compila para asegurar que los tipos sean correctos. Si no coinciden los tipos no se generan avisos de compilador, sino que se generan errores que se deben corregir antes de que el compilador termine de compilar la clase. Para cada tipo se define explícitamente el único conjunto de valores que puede expresar, junto con un conjunto definido de operaciones que están permitidas. Por ejemplo, los tipos numéricos int y float se pueden sumar entre ellos, pero los tipos boolean no. Tipos numéricos Los tipos numéricos son los que contienen números y pueden ser de dos clases, los que guardan números de valor completo sin parte fraccionaria, llamados enteros, y los que pueden almacenar una parte fraccionaria, llamados números en coma flotante. La magnitud del rango o grado de precisión de una componente fraccionaria que se va a necesitar dependerá de su aplicación. Todos estos tipos en Java tienen definido un rango explícito y un comportamiento matemático. La mayor parte del código no portable de otros lenguajes está repleto de problemas debidos al comportamiento no especificado del tipo int. La base de este problema reside en un concepto llamado tamaño de palabra de la máquina. El tamaño de palabra de una CPU dada está determinado por el número de bits que utiliza internamente para representar sus registros más básicos, que se utilizan para almacenar y manipular los números. Debido a la evolución de los PC y al tamaño de palabra variable de estos, algunos compiladores implementan int como un entero de tamaño de palabra de 32 bits, otros puede que sólo tengan 16 bits, y los compiladores de los sistemas más modernos puede que incluso utilicen 64 bits. En Java, no hay una conexión entre el tamaño de palabra de la máquina y el rango de un tipo numérico. Un valor int siempre tiene 32 bits en todos los intérpretes Java, independientemente de la plataforma de la que se trate. Esto permite que los programas que se escriban tengan garantizada su ejecución en cualquier arquitectura sin tener que transportarlos. Enteros Todos los tipos numéricos de Java son valores con signo. Esta ausencia de signo reduce el número de tipos de entero a cuatro, cada uno de los cuales representa 1, 2, 4 y 8 bytes de almacenamiento. Veamos en detalle cada uno de los cuatro tipos, byte, short, int y long. byte byte es un tipo de 8 bits con signo. Su rango comprende desde -128 a 127. Es especialmente útil cuando se tiene un flujo de bytes externos recibidos desde una red o archivo. Si se necesita analizar gramaticalmente un protocolo de red o un formato de archivo, o resolver problemas de ordenamiento de bytes, el tipo byte es el apropiado. Las variables byte se declaran utilizando la palabra clave byte. Por ejemplo, el código siguiente declara dos variables byte llamadas b y c, inicializando c con el valor hexadecimal 0x55. byte b; byte c = 0x55; En general, se debería evitar la utilización del tipo byte excepto cuando se trabaje con manipulación de bits. Para los enteros normales, que se utilizan para contar y operar, int, que se describe más adelante, es una elección mucho más adecuada. short short es un tipo de 16 bits con signo. Su rango comprende desde -32768 a 32767. Probablemente es el tipo de Java menos utilizado. Ahora que las computadoras de 16 bits empiezan a estar en desuso ya no hay muchos valores short con los que trabajar. Ejemplos de declaraciones de variables short: short s; short t = 0x55aa; int int es un tipo de 32 bits con signo. su rango comprende desde -2.147.483.648 a 2.147.483.647. Es el tipo más utilizado habitualmente para almacenar valores enteros simples. Con un rango de miles de millones, es ideal para la mayoría de las iteraciones con matrices y para contar. Siempre que se tenga una expresión con enteros que incluya byte, short, int y números literales, la expresión completa se promociona a int antes de realizar el cálculo. Ejemplos de declaraciones de variables int: int i; int j = 0x55aa0000; long long es un tipo de 64 bits con signo. Hay algunas ocasiones en las que un tipo int no es lo suficientemente grande como para guardar un valor deseado. Cuando se calcular expresiones enteras con números grandes, una multiplicación puede generar algunos valores intermedios de miles de billones. También, cuando se calcula el tiempo, el número de milisegundos en un año es de cerca de 30.000 millones y se desbordará un int de 32 bits. En estos casos se necesita utilizar un long. Ejemplos de declaraciones de variables long: long m; long n = 0x55aa000055aa0000; Tabla de anchuras y rangos para cada uno de los tipos enteros. Nombre Anchura Rango long 64 -9.223.372.036.854.775.808..9.223.372.036.854.775.807 int 32 -2.147.483.648..2.147.483.647 short 16 -32.768..32.767 byte 8 -128..127 Números en coma flotante Los números en coma flotante, también conocidos como números reales en otros lenguajes, se utilizan cuando se calculan funciones que requieren precisión fraccionaria. Los cálculos complejos, como la raíz cuadrada, o trigonométricas, como el seno y el coseno, tienen como resultado un valor cuya precisión requiere un tipo en coma flotante. Hay dos clases de tipos en coma flotante, float y double, como se describen: Nombre Anchura Rango double 64 1.7e-308..1.7e+308 float 32 3.4e-038..3.4e+038 float La precisión simple, especificada por la palabra clave float, utiliza 32 bits para almacenar un valor. La precisión simple es más rápida en algunos procesadores y ocupa la mitad de espacio, pero comenzará a ser imprecisa cuando los valores sean muy grandes o muy pequeños. Ejemplos de declaraciones de variables float: float f; float f2 = 3.14f; double La precisión doble, especificada por la palabra clave double, utiliza 64 bits para almacenar un valor. Realmente la precisión doble es más rápida que la simple en algunos procesadores modernos que han sido optimizados para cálculos matemáticos a alta velocidad. Cuando se necesita mantener la precisión tras muchos cálculos iterativos, o está manipulando números de gran valor, double es la mejor opción. Ejemplos de declaraciones de variables double: double d; double pi = 3.14159365358979323846; Conversión de tipos Hay situaciones en las cuales se tiene un valor de un tipo dado y se desea almacenar ese valor en una variable de un tipo diferente. En algunos tipos es posible almacenar simplemente el valor sin una conversión de tipos; lo que se denomina conversión automática. Esto sólo es posible en Java si el compilador reconoce que la variable destino tiene la suficiente precisión para contener el valor origen, como almacenar un valor byte en una variable int. A esto se le llama ensanchamiento o promoción, dado que el tipo más pequeño se ensancha o promociona al tipo compatible más grande. Si por el contrario, se desea asignar un valor de variable int a una variable byte se necesita realizar una conversión de tipos explícita. A esto se le llama estrechamiento, dado que se estrecha explícitamente el valor para que quepa en el destino. La conversión de un tipo se realiza poniendo delante un nombre de tipo entre paréntesis, por ejemplo, (tipo) valor. El código siguiente demuestra la conversión de tipos de int a byte. Si el valor del entero fuese mayor que el rango de un byte, se reduciría al módulo (resto de la división) del rango de byte. int a = 100; byte b = (byte) a; Caracteres Dado que Java utiliza Unicode para representar los caracteres de una cadena, el tipo char es de 16 bits sin signo. El rango de un carácter es de 0 a 65536. No hay caracteres negativos. Unicode es una unificación de docenas de conjuntos de caracteres, incluyendo el latín, griego, arábigo, cirílico, hebreo, katakana, hangul y muchos más. Ejemplos de declaraciones char: char c; char c2 = 0xf132; char c3 = 'a'; char c4 = '\n'; Aunque no se utilicen los caracteres como enteros, puede operar con ellos como si lo fueran. Esto permite sumar dos caracteres o incrementar el valor de una variable carácter. int tres = 3; char uno = '1'; char cuatro = (char) (tres + uno); La variable cuatro termina con un '4' almacenado en ella. Observe que uno fue promocionado a int en la expresión, por lo que se requiere la conversión de tipos para volver a char antes de la asignación a cuatro. Booleanos Java tiene un tipo simple para los valores lógicos, llamado boolean. Sólo puede tomar uno de estos dos posibles valores, true (verdadero) o false (falso) que son palabras reservadas. Este es el tipo que devuelven todos los operadores de comparación o que se requiere en todos los operadores de control de flujo que se explicarán en capítulos posteriores. Ejemplo de una declaración de tipo boolean: boolean terminado = false; Fuente: http://www.geocities.com/CollegePark/Quad/8901/cap01.htm Existen dos diferentes tipos de datos simples definidos por el usuario: enumerados y subrago. Tipos enumerados. Los tipos enumerados se componen de una lista de identificadores encerrados entre paréntesis y separados por comas. Ejem. Type Estaciones = (primavera, verano, otoño, invierno); Colores (rojo, amarillo, verde, azul, violeta); Los tipos enumerados son ordinales ya que llevan asociado cada uno un número entero, empezando por el primero, al que se le asigna el O, al segundo un 1, y así sucesivamente, por lo que no es independiente el orden de declaración. Un valor de tipo enumerado no puede pertenecer a dos declaraciones de tipo distintas y no pueden leerse desde teclado, ni escribirse en pantalla. Tipos subrango. Es un subconjunto de un tipo ordinal (enteros, boolean, carácter y enumerado) que se especifica indicando el primero y el último elemento del conjunto. Ejem. 1 Type Identificador=primerelemento..ultimoelemento; Ejem. 2 Type Fecha= 1..31; Var Dia: Fecha; Los tipos enteros, carácter, booleanos, enumerados y subrango se denominan tipos ordinales. Un tipo ordinal representa una secuencia ordenada de valores individuales, a los que se puede aplicar los conceptos de predecesor y sucesor. En cada tipo de datos ordinales hay un primer valor y un último valor.