← CC2008

Aliases

Semestre 02, 2026

Referencias y creación de objetos

Idea central

En Java, cuando creamos un objeto, lo que realmente obtenemos es una referencia a un área de memoria donde está almacenado el objeto.

Partes de la creación


Persona p = new Persona();
Persona es el tipo (la clase).
p es una referencia al objeto.
new Persona() crea el objeto en memoria.

Ejemplo


Persona p1 = new Persona();
p1.nombre = "Ana";

Persona p1 = new Persona();
p1.nombre = "Ana";
Persona p1 = new Persona();

Crea el objeto en memoria y guarda su referencia en p1.


Persona p1 = new Persona();
p1.nombre = "Ana";
p1.nombre = "Ana";

Asigna el texto Ana al atributo nombre del objeto.

En memoria


p1 ---> [ Objeto Persona (nombre: Ana) ]

Referencias múltiples (aliases)

Dos variables pueden apuntar al mismo objeto:


Persona p2 = p1;
p2.nombre = "Luis";

Persona p2 = p1;
p2.nombre = "Luis";
Persona p2 = p1;

p2 recibe la misma referencia que p1: ambos apuntan al mismo objeto.


Persona p2 = p1;
p2.nombre = "Luis";
p2.nombre = "Luis";

Cambiar el nombre por medio de p2 afecta también a p1: es el mismo objeto.

En memoria


p1 ---> [ Objeto Persona (nombre: Luis) ] <--- p2

Modificaciones compartidas

Ambas referencias afectan al mismo objeto. Cualquier modificación hecha por medio de una referencia será visible también a través de la otra:


System.out.println(p1.nombre); // Luis
System.out.println(p2.nombre); // Luis

Precaución

Cuidado

Este comportamiento puede provocar errores difíciles de detectar si se asume que p1 y p2 son objetos distintos.

Copia independiente

Para crear una copia independiente, se necesita una nueva instancia:


Persona p3 = new Persona();

// copia el valor del nombre, no la referencia
p3.setNombre(p1.getNombre());

Persona p3 = new Persona();

// copia el valor del nombre, no la referencia
p3.setNombre(p1.getNombre());
Persona p3 = new Persona();

Crea una nueva instancia independiente, con su propia memoria.


Persona p3 = new Persona();

// copia el valor del nombre, no la referencia
p3.setNombre(p1.getNombre());
p3.setNombre(p1.getNombre());

Copia el valor del nombre, no la referencia: p3 queda independiente de p1.

Copia superficial y copia profunda

Copia superficial (shallow copy): copia el valor del atributo, no las referencias internas.
Copia profunda (deep copy): en objetos con atributos que también son objetos.
Crea un nuevo objeto junto con nuevas instancias de todos los objetos que contiene internamente.
Garantiza que no se comparta memoria entre el objeto original y su copia.

Comparación de referencias


if (p1 == p2) {
    System.out.println("Misma referencia");
}
== compara referencias, no contenido.
Para comparar contenido usamos .equals().

Recolector de basura

Java maneja automáticamente la memoria.


p1 = null;

Si no hay más referencias a un objeto, el recolector puede liberar su memoria. No tenemos control directo sobre este proceso, pero podemos sugerirlo.


System.gc();

Clases útiles en Java

Java incluye clases listas para usar. Estudiaremos cada una junto con su paquete:

Stringjava.lang
Mathjava.lang
Randomjava.util
NumberFormatjava.text
DecimalFormatjava.text
Scannerjava.util

Paquetes e import

Sin import

String y Math pertenecen a java.lang: están disponibles siempre.

Requieren import

Random, Scanner, NumberFormat y DecimalFormat sí deben importarse antes de usarse.

String

Representa una cadena de texto. Es inmutable: cada operación devuelve un nuevo String. Métodos más usados:

length(): cantidad de caracteres.
charAt(i): carácter en la posición i.
substring(a, b): subcadena entre índices.
indexOf(txt): posición de un texto.
replace(a, b): reemplaza texto.
equals(txt): compara contenido.

String — ejemplo


String nombre = "María López";

System.out.println(nombre.length());        // 11
System.out.println(nombre.toUpperCase());   // MARÍA LÓPEZ
System.out.println(nombre.charAt(0));       // M
System.out.println(nombre.substring(0, 5)); // María
System.out.println(nombre.indexOf("López")); // 6
System.out.println(nombre.replace("María", "Ana")); // Ana López
Recuerda

Para comparar texto usa .equals(), no == (que compara referencias).

Math

Ofrece funciones matemáticas mediante métodos estáticos: se usan con Math. sin crear objetos.

abs(x): valor absoluto.
max(a,b) / min(a,b): mayor y menor.
pow(a,b): potencia. sqrt(x): raíz.
round, ceil, floor: redondeo.
random(): número entre 0.0 y 1.0.
PI, E: constantes.

Math — ejemplo


int maximo = Math.max(10, 20);      // 20
double raiz = Math.sqrt(144);       // 12.0
double potencia = Math.pow(2, 10);  // 1024.0
long redondeo = Math.round(3.7);    // 4
double area = Math.PI * Math.pow(5, 2); // círculo r=5

Random

Genera valores aleatorios. A diferencia de Math, sí requiere crear un objeto e importarse desde java.util.


import java.util.Random;

Random rnd = new Random();
int numero  = rnd.nextInt(10);   // entero de 0 a 9
double dec  = rnd.nextDouble();  // decimal de 0.0 a 1.0
boolean bit = rnd.nextBoolean(); // true o false

NumberFormat

Idea central

Da formato a números según una configuración regional (locale): moneda, porcentaje o número general, con separadores adecuados.

getCurrencyInstance(): formato de moneda.
getPercentInstance(): formato de porcentaje.
getNumberInstance(): número con separadores.

NumberFormat — ejemplo


import java.text.NumberFormat;

NumberFormat moneda = NumberFormat.getCurrencyInstance();
System.out.println(moneda.format(1234.5)); // $1,234.50

NumberFormat pct = NumberFormat.getPercentInstance();
System.out.println(pct.format(0.75));      // 75%

NumberFormat num = NumberFormat.getNumberInstance();
System.out.println(num.format(1000000));   // 1,000,000

El símbolo de moneda y los separadores dependen del Locale del sistema.

DecimalFormat

Idea central

Permite definir un patrón personalizado para dar formato a un número: cuántos decimales mostrar, separadores de miles, porcentajes, etc.

El patrón se arma con estos símbolos:

Símbolo 0

Dígito obligatorio

Siempre muestra un dígito en esa posición. Si el número no lo tiene, rellena con un cero.


new DecimalFormat("00.0").format(7.5); // 07.5

Símbolo #

Dígito opcional

Muestra el dígito solo si existe. Si no hay dígito en esa posición, no imprime nada (sin ceros de relleno).


new DecimalFormat("##.##").format(7.5); // 7.5

Símbolo .

Separador decimal

Marca dónde empieza la parte decimal del número.


new DecimalFormat("0.00").format(3.5); // 3.50

Símbolo ,

Separador de miles

Agrupa la parte entera de tres en tres para facilitar la lectura.


new DecimalFormat("#,##0").format(1000000); // 1,000,000

Símbolo %

Porcentaje

Multiplica el número por 100 y añade el símbolo % al final.


new DecimalFormat("0.0%").format(0.85); // 85.0%

DecimalFormat — ejemplo


import java.text.DecimalFormat;

DecimalFormat df = new DecimalFormat("#,##0.00");
System.out.println(df.format(1234.5));   // 1,234.50

DecimalFormat df2 = new DecimalFormat("0.###");
System.out.println(df2.format(3.14159)); // 3.142

DecimalFormat df3 = new DecimalFormat("0.0%");
System.out.println(df3.format(0.85));    // 85.0%
Diferencia

NumberFormat usa formatos predefinidos por región; DecimalFormat te da control total mediante un patrón propio.

Scanner

Lee datos de entrada, típicamente desde el teclado (System.in).


import java.util.Scanner;

Scanner sc = new Scanner(System.in);
System.out.print("Edad: ");
int edad = sc.nextInt();

Tipos primitivos vs objetos

Java distingue entre:

Primitivos: int, double, char, boolean...
Objetos: Integer, Double, Character, Boolean...

Clases Wrapper

Cada tipo primitivo tiene una clase equivalente:

PrimitivoClase Wrapper
intInteger
doubleDouble
charCharacter
booleanBoolean

Permiten usar métodos útiles y trabajar con colecciones:


Integer edad = 25;
System.out.println(edad.toString());

Para qué sirven los wrappers

Envolver un primitivo en un objeto nos da capacidades que el primitivo no tiene:

Convertir texto a número con parseInt, parseDouble.
Constantes útiles: Integer.MAX_VALUE, MIN_VALUE.
Guardar números en colecciones (ArrayList).
Pueden valer null: representan la ausencia de valor.

Autoboxing y unboxing

Java convierte automáticamente entre tipos primitivos y sus equivalentes en clases wrapper.

Autoboxing

Convierte un tipo primitivo a su clase wrapper cuando se requiere un objeto.


int numero = 20;
Integer edad = numero; // int → Integer
Unboxing

Proceso inverso: convierte un objeto wrapper a su tipo primitivo.


Integer altura = 180;
int h = altura; // Integer → int

Convertir texto a número

Muy usado

Los datos que llegan del teclado, de un archivo o de un formulario siempre son texto. Los wrappers los convierten al número que necesitamos.


int cantidad  = Integer.parseInt("42");       // "42"   → 42
double precio = Double.parseDouble("19.99");   // "19.99" → 19.99
boolean activo = Boolean.parseBoolean("true"); // "true" → true

int total = cantidad * 2; // ya podemos operar como número

Convertir número a texto

El proceso inverso: pasar un número a String para mostrarlo o guardarlo.


int edad = 25;

String a = Integer.toString(edad); // "25"
String b = String.valueOf(edad);   // "25"
String c = "Edad: " + edad;        // "Edad: 25"

Constantes y métodos útiles

Cada wrapper trae valores límite y métodos estáticos listos para usar:


System.out.println(Integer.MAX_VALUE); // 2147483647
System.out.println(Integer.MIN_VALUE); // -2147483648

int mayor = Integer.max(8, 3);    // 8
int menor = Integer.min(8, 3);    // 3
int comp  = Integer.compare(5, 9); // -1 (5 es menor)

Character: analizar texto

Útil para validar lo que el usuario escribe, carácter por carácter:


char c = '7';

Character.isDigit(c);        // true  ¿es un dígito?
Character.isLetter('A');     // true  ¿es una letra?
Character.isWhitespace(' '); // true  ¿es un espacio?
Character.toUpperCase('a');  // 'A'   pasar a mayúscula

Wrappers en colecciones

Regla

Las colecciones como ArrayList solo guardan objetos, no primitivos. Por eso usamos Integer en lugar de int.


import java.util.ArrayList;

ArrayList<Integer> notas = new ArrayList<>();
notas.add(90);   // autoboxing: int → Integer
notas.add(85);

int suma = notas.get(0) + notas.get(1); // unboxing → 175

Enumeraciones (enum)

Tipo especial que permite definir un conjunto limitado de valores:


public enum Dia {
    LUNES, MARTES, MIERCOLES, JUEVES, VIERNES
}

Dia hoy = Dia.LUNES;

Se comportan como clases y se pueden comparar:


if (hoy == Dia.LUNES) {
    System.out.println("Inicio de semana");
}

Beneficios

Código más legible.
Funciones ya implementadas.
Menos errores.
Mejores prácticas de programación orientada a objetos.