Tipos primitivos y Strings
En Java, el sistema de tipos está claramente dividido entre tipos primitivos y tipos de referencia. Los tipos primitivos representan los bloques fundamentales para almacenar datos simples, mientras que los Strings constituyen una clase especial que merece atención particular debido a su uso frecuente en la programación.
Tipos primitivos numéricos enteros
Java proporciona cuatro tipos primitivos para representar números enteros, cada uno con diferentes rangos y usos específicos:
byte
: Ocupa 8 bits y almacena valores entre -128 y 127. Es útil para ahorrar memoria cuando trabajas con grandes cantidades de datos pequeños.
byte temperatura = 25;
byte nivel = -10;
short
: Utiliza 16 bits con un rango de -32,768 a 32,767. Se emplea ocasionalmente cuando el rango debyte
resulta insuficiente.
short poblacion = 15000;
short altitud = -200;
int
: El tipo entero más utilizado, ocupa 32 bits y maneja valores desde -2,147,483,648 hasta 2,147,483,647. Es la opción predeterminada para números enteros.
int edad = 25;
int distancia = 1500000;
long
: Emplea 64 bits para números muy grandes, desde -9,223,372,036,854,775,808 hasta 9,223,372,036,854,775,807. Requiere el sufijoL
para valores literales.
long habitantes = 7800000000L;
long microsegundos = 1634567890123L;
Tipos primitivos numéricos decimales
Para representar números con decimales, Java ofrece dos opciones con diferentes precisiones:
float
: Utiliza 32 bits con precisión simple. Los valores literales requieren el sufijof
. Tiene aproximadamente 7 dígitos decimales de precisión.
float precio = 19.99f;
float temperatura = -15.5f;
double
: Emplea 64 bits con precisión doble y es el tipo predeterminado para números decimales. Ofrece aproximadamente 15 dígitos decimales de precisión.
double pi = 3.141592653589793;
double salario = 2500.75;
Tipo primitivo lógico
El tipo boolean
representa valores lógicos y solo puede almacenar dos estados:
boolean esActivo = true;
boolean estaCompleto = false;
Este tipo resulta fundamental para expresiones condicionales y control de flujo en tus programas.
Tipo primitivo carácter
El tipo char
almacena un único carácter Unicode utilizando 16 bits. Los valores literales se escriben entre comillas simples:
char inicial = 'A';
char simbolo = '@';
char unicode = '\u0041'; // Representa 'A' en Unicode
El tipo String
Aunque String
no es un tipo primitivo, sino una clase, su uso es tan frecuente que merece consideración especial. Representa secuencias de caracteres y se declara con comillas dobles:
String nombre = "María";
String mensaje = "Bienvenido al curso de Java";
String vacio = "";
Los Strings en Java son inmutables, lo que significa que una vez creados, su contenido no puede modificarse. Cada operación que aparenta modificar un String en realidad crea un nuevo objeto:
String saludo = "Hola";
String saludoCompleto = saludo + " mundo"; // Crea un nuevo String
Diferencias fundamentales
La principal diferencia entre tipos primitivos y String radica en cómo se almacenan en memoria:
- Tipos primitivos: Se almacenan directamente en la pila (stack) con su valor real.
- String: Se almacena como objeto en el heap, mientras que la variable contiene una referencia a ese objeto.
int numero = 42; // Valor directo en memoria
String texto = "Java"; // Referencia a objeto en heap
Esta distinción afecta la comparación de valores. Los tipos primitivos se comparan directamente con ==
, mientras que los Strings requieren métodos específicos para comparar su contenido real.
Los tipos primitivos también tienen valores predeterminados cuando se utilizan como campos de clase: los numéricos se inicializan a cero, boolean
a false
, y char
al carácter nulo. Los Strings, por el contrario, se inicializan a null
como cualquier objeto.
Declaración e inicialización de variables
La declaración de variables en Java sigue una sintaxis específica que establece el tipo de dato que puede almacenar y el nombre que utilizaremos para referenciarla. Una variable actúa como un contenedor etiquetado que reserva espacio en memoria para guardar información.
Sintaxis básica de declaración
La forma más simple de declarar una variable consiste en especificar el tipo seguido del nombre de la variable:
int edad;
String nombre;
double salario;
boolean activo;
En estos ejemplos, hemos reservado espacio en memoria pero las variables aún no contienen valores útiles. Las variables locales deben inicializarse antes de su primer uso, mientras que las variables de instancia reciben valores predeterminados automáticamente.
Inicialización de variables
La inicialización asigna un valor inicial a la variable mediante el operador de asignación =
. Puedes realizar este proceso después de la declaración:
int edad;
edad = 25;
String nombre;
nombre = "Ana";
double salario;
salario = 2800.50;
Declaración e inicialización simultánea
La práctica más común combina declaración e inicialización en una sola línea, resultando en código más limpio y legible:
int edad = 25;
String nombre = "Ana";
double salario = 2800.50;
boolean esEmpleado = true;
char categoria = 'A';
También puedes declarar múltiples variables del mismo tipo en una línea, aunque es menos recomendable para mantener la claridad:
int x = 10, y = 20, z = 30;
double precio = 19.99, descuento = 0.15;
Reglas de nomenclatura
Los nombres de variables en Java deben seguir convenciones específicas que mejoran la legibilidad del código:
- Camel Case: Utiliza la primera letra en minúscula y la primera letra de cada palabra posterior en mayúscula.
String nombreCompleto = "Juan Pérez";
int numeroTelefono = 612345678;
boolean estaActivo = true;
- Caracteres permitidos: Los nombres pueden contener letras, dígitos, guiones bajos y símbolos de dólar, pero deben comenzar con una letra.
int valor1 = 100; // Válido
int _contador = 0; // Válido pero no recomendado
int $precio = 25; // Válido pero no recomendado
// int 2valor = 50; // Inválido - no puede empezar con dígito
Inicialización con valores calculados
Las variables pueden inicializarse con expresiones que se evalúan en el momento de la declaración:
int base = 10;
int altura = 5;
int area = base * altura; // Resultado: 50
String saludo = "Hola";
String mensaje = saludo + " mundo"; // Resultado: "Hola mundo"
boolean mayor = edad > 18; // Evaluación lógica
Constantes con final
Utiliza la palabra clave final
para crear variables que no pueden modificarse después de su inicialización. Por convención, las constantes se escriben en mayúsculas:
final int DIAS_SEMANA = 7;
final double PI = 3.141592653589793;
final String EMPRESA = "TechCorp";
Intentar modificar una variable final resultará en un error de compilación:
final int MAX_USUARIOS = 100;
// MAX_USUARIOS = 200; // Error de compilación
Ámbito y visibilidad básica
El ámbito de una variable determina dónde puede utilizarse dentro del código. Las variables declaradas dentro de un método tienen ámbito local y solo existen mientras se ejecuta ese método:
public void calcular() {
int resultado = 0; // Variable local
boolean completado = false; // Variable local
// Las variables solo son accesibles dentro de este método
resultado = 100;
completado = true;
}
Mejores prácticas de inicialización
Inicializa las variables lo más cerca posible de su primer uso para mejorar la legibilidad y reducir errores:
// Menos recomendable
int contador;
String mensaje;
boolean encontrado;
// ... muchas líneas de código ...
contador = 0;
mensaje = "Procesando";
encontrado = false;
// Más recomendable
// ... código previo ...
int contador = 0;
String mensaje = "Procesando";
boolean encontrado = false;
Utiliza nombres descriptivos que comuniquen claramente el propósito de la variable:
// Menos claro
int n = 25;
String s = "Juan";
boolean b = true;
// Más claro
int edadUsuario = 25;
String nombreCliente = "Juan";
boolean pedidoCompleto = true;
Inicialización con valores por defecto
Cuando declares variables de instancia en una clase, Java les asigna valores predeterminados automáticamente:
public class Usuario {
int edad; // Se inicializa a 0
String nombre; // Se inicializa a null
boolean activo; // Se inicializa a false
double salario; // Se inicializa a 0.0
}
Sin embargo, las variables locales deben inicializarse explícitamente antes de su uso para evitar errores de compilación.
Conversión de tipos
La conversión de tipos (type casting) es el proceso mediante el cual transformamos un valor de un tipo de dato a otro tipo diferente. En Java, esta operación es fundamental cuando necesitas trabajar con datos de diferentes tipos o cuando realizas cálculos que requieren compatibilidad entre tipos.
Conversión implícita (widening)
Java realiza conversiones automáticas cuando no existe riesgo de pérdida de información. Esta conversión implícita, también conocida como widening casting, ocurre cuando asignas un valor de un tipo más pequeño a un tipo más grande:
int numero = 100;
long numeroLargo = numero; // int → long (automático)
double decimal = numeroLargo; // long → double (automático)
byte pequeño = 10;
int mediano = pequeño; // byte → int (automático)
float flotante = mediano; // int → float (automático)
La jerarquía de conversión implícita sigue este orden de menor a mayor capacidad:
byte
→ short
→ int
→ long
→ float
→ double
También existe conversión automática desde char
hacia tipos numéricos:
char letra = 'A';
int codigoAscii = letra; // char → int (automático)
System.out.println(codigoAscii); // Imprime: 65
Conversión explícita (narrowing)
Cuando intentas asignar un valor de un tipo más grande a uno más pequeño, debes realizar una conversión explícita utilizando el operador de cast. Esta operación puede resultar en pérdida de información:
double decimal = 25.7;
int entero = (int) decimal; // double → int (explícito)
System.out.println(entero); // Imprime: 25 (se pierde la parte decimal)
long numeroGrande = 300L;
byte pequeño = (byte) numeroGrande; // long → byte (explícito)
System.out.println(pequeño); // Imprime: 44 (valor truncado)
La sintaxis del cast explícito consiste en colocar el tipo destino entre paréntesis antes del valor a convertir:
// Sintaxis: (tipoDestino) valorOriginal
int resultado = (int) 15.9; // resultado = 15
short corto = (short) 1000; // corto = 1000
char caracter = (char) 65; // caracter = 'A'
Conversión entre char e int
El tipo char
tiene una relación especial con los números enteros debido a que representa caracteres mediante códigos Unicode. Puedes convertir entre caracteres y sus códigos numéricos:
// char → int (conversión implícita)
char vocal = 'a';
int codigo = vocal;
System.out.println(codigo); // Imprime: 97
// int → char (conversión explícita)
int numero = 65;
char letra = (char) numero;
System.out.println(letra); // Imprime: A
// Operaciones aritméticas con char
char siguiente = (char) (vocal + 1);
System.out.println(siguiente); // Imprime: b
Conversión con operaciones aritméticas
Durante las operaciones aritméticas, Java aplica reglas específicas de promoción automática que afectan el tipo del resultado:
byte a = 10;
byte b = 20;
// byte resultado = a + b; // Error: la suma produce int
int resultado = a + b; // Correcto: resultado es int
short x = 100;
short y = 200;
short suma = (short) (x + y); // Cast necesario para asignar a short
float precio = 19.99f;
int cantidad = 3;
float total = precio * cantidad; // int se promociona a float automáticamente
La regla general establece que las operaciones aritméticas con tipos menores que int
siempre producen un resultado de tipo int
.
Conversión de String a tipos primitivos
Java proporciona métodos específicos en las clases wrapper para convertir Strings a tipos primitivos:
// String → int
String textoNumero = "123";
int numero = Integer.parseInt(textoNumero);
// String → double
String textoDecimal = "15.75";
double decimal = Double.parseDouble(textoDecimal);
// String → boolean
String textoBooleano = "true";
boolean valor = Boolean.parseBoolean(textoBooleano);
// String → long
String textoLargo = "987654321";
long numeroLargo = Long.parseLong(textoLargo);
Conversión de tipos primitivos a String
Para convertir tipos primitivos a String, utiliza el método valueOf()
de la clase String o la concatenación con una cadena vacía:
int edad = 25;
String edadTexto = String.valueOf(edad); // Método recomendado
String edadTexto2 = edad + ""; // Concatenación simple
double precio = 29.99;
String precioTexto = String.valueOf(precio);
boolean activo = true;
String activoTexto = String.valueOf(activo); // Resultado: "true"
Manejo de errores en conversiones
Las conversiones de String a tipos numéricos pueden fallar si el formato no es válido. En situaciones básicas, es importante reconocer que esto puede ocurrir:
String textoInvalido = "abc123";
// int numero = Integer.parseInt(textoInvalido); // Causaría error en ejecución
// Ejemplo de uso seguro con números válidos
String numeroValido = "456";
int resultado = Integer.parseInt(numeroValido); // Funciona correctamente
Pérdida de precisión en conversiones
Cuando conviertes de tipos con mayor precisión a tipos con menor precisión, debes considerar la posible pérdida de información:
double preciso = 123.456789;
float menosPreciso = (float) preciso;
System.out.println(preciso); // 123.456789
System.out.println(menosPreciso); // 123.45679 (pérdida de precisión)
long numeroGrande = 2147483648L; // Mayor que int máximo
int truncado = (int) numeroGrande;
System.out.println(truncado); // -2147483648 (overflow)
Conversiones útiles en la práctica
En situaciones reales de programación, las conversiones más frecuentes incluyen:
// Trabajar con entrada de usuario
String entrada = "25";
int edad = Integer.parseInt(entrada);
// Cálculos mixtos
int estudiantes = 30;
double porcentaje = 0.85;
int aprobados = (int) (estudiantes * porcentaje);
// Formateo de salida
double resultado = 15.0 / 4.0;
int parteEntera = (int) resultado;
System.out.println("Resultado: " + parteEntera); // Resultado: 3
Las conversiones de tipos representan una herramienta esencial para manipular datos de diferentes formatos y realizar cálculos efectivos en tus programas Java. Dominar estas técnicas te permitirá trabajar con flexibilidad entre los distintos tipos de datos disponibles.
Fuentes y referencias
Documentación oficial y recursos externos para profundizar en Java
Documentación oficial de Java
Alan Sastre
Ingeniero de Software y formador, CEO en CertiDevs
Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Java es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.
Más tutoriales de Java
Explora más contenido relacionado con Java y continúa aprendiendo con nuestros tutoriales gratuitos.
Aprendizajes de esta lección
- Comprender los tipos primitivos numéricos, lógicos y de carácter en Java.
- Diferenciar entre tipos primitivos y objetos String, y su almacenamiento en memoria.
- Aprender a declarar, inicializar y nombrar variables correctamente.
- Entender la conversión implícita y explícita entre tipos de datos.
- Manejar conversiones entre Strings y tipos primitivos, y reconocer posibles errores y pérdidas de precisión.