Saltar a contenido

Semana 3 - Atributos de una clase en Java - Datos primitivos, clases envolventes, casteo y parseo


1. ¿Qué es un atributo en Java?

Un atributo (también llamado campo o variable de instancia) es una variable declarada dentro de una clase, fuera de cualquier método, que describe el estado de los objetos que se creen a partir de dicha clase.

public class Persona {
    // Atributos
    String nombre;      // referencia
    int edad;           // primitivo
    Double estatura;    // envolvente
}

2. Datos primitivos

Java define ocho tipos primitivos que almacenan valores simples y no son objetos:

Tipo Tamaño Rango aproximado Ejemplo literal
byte 8 bits -128 … 127 (byte) 100
short 16 b -32 768 … 32 767 (short) 5000
int 32 b -2³¹ … 2³¹-1 42
long 64 b -2⁶³ … 2⁶³-1 99L
float 32 b IEEE 754 3.14f
double 64 b IEEE 754 2.71828
char 16 b 0 … 65 535 (Unicode) 'A'
boolean 1 bit* true / false true

*El tamaño exacto de boolean depende de la JVM, conceptualmente solo almacena 1 bit.

public class PrimitivosDemo {
    byte  b = 120;
    short s = 30_000;
    int   i = 1_000_000;
    long  l = 9_000_000_000L;
    float  f = 1.234f;
    double d = 3.141592653589793;
    char   c = 'ñ';
    boolean activo = false;
}

3. Clases envolventes (Wrapper Classes)

Cada primitivo tiene su clase envolvente en java.lang que lo “empaqueta” como un objeto. Esto permite:

  • Almacenarlos en colecciones (List<Integer>).
  • Aprovechar utilidades (Integer.parseInt, Double.compare).
  • Representar null.
Primitivo Wrapper Constantes útiles
byte Byte Byte.MIN_VALUE
short Short Short.MAX_VALUE
int Integer Integer.SIZE (bits)
long Long Long.BYTES
float Float Float.NaN
double Double Double.POSITIVE_INF
char Character Character.isDigit(c)
boolean Boolean Boolean.TRUE
public class WrapperDemo {
    Integer stock = null;       // null es válido
    Double precio = 19.99;      // autoboxing
    Boolean disponible = true;  // autoboxing
}

4. Diferencias clave: primitivo vs. envolvente

Aspecto Primitivo Envoltorio
Valor por defecto 0, false, \u0000 null
Almacenamiento Stack Heap
Rendimiento Más rápido Más lento (creación de obj.)
Colecciones No admite directamente Sí (List<Integer>)
Métodos Ninguno Muchos (parseXxx, valueOf)

5. Casteo (Casting)

Convertir un valor de un tipo a otro compatible.

5.1 Casteo entre primitivos (widening & narrowing)

  • Widening (implícito): de menor a mayor precisión
    int → long, float → double
  • Narrowing (explícito): de mayor a menor precisión (pérdida)
    double → int, long → short
double pi = 3.1416;
int    enteroPi = (int) pi;  // 3  (truncamiento)

long  grande = 1_000_000L;
int   peque  = (int) grande; // ok si cabe, pérdida si no

5.2 Casteo entre objetos (up/down casting)

Object obj = "Hola";        // upcasting implícito
String s   = (String) obj;  // downcasting explícito

6. Parseo (Parsing)

Convertir cadenas (u otros tipos) a valores primitivos/envolventes.

6.1 Métodos estáticos parseXxx

String edadTxt = "28";
int edad = Integer.parseInt(edadTxt);

String precioTxt = "19.90";
double precio = Double.parseDouble(precioTxt);

6.2 Métodos valueOf

Devuelve el wrapper en vez del primitivo:

Integer edadObj = Integer.valueOf("28");
Boolean flag    = Boolean.valueOf("true");

6.3 Manejo de errores

try {
    int x = Integer.parseInt("ABC");  // lanza NumberFormatException
} catch (NumberFormatException e) {
    System.err.println("Entrada inválida: " + e.getMessage());
}

7. Ejemplos integrados

7.1 Ejemplos con tipos primitivos y wrappers

public class Producto {
    // Primitivos
    private int    id;           // nunca null
    private double pesoKg;       // 0.0 por defecto

    // Wrappers
    private Integer stock;       // puede ser null
    private BigDecimal precio;   // precisión decimal

    // Constructor
    public Producto(int id, double pesoKg, Integer stock, BigDecimal precio) {
        this.id     = id;
        this.pesoKg = pesoKg;
        this.stock  = stock;
        this.precio = precio;
    }

    // Getters & setters
    public int getId() { return id; }
    public Integer getStock() { return stock; }
    public void setStock(Integer stock) { this.stock = stock; }

    @Override
    public String toString() {
        return String.format("Producto{id=%d, peso=%.2f kg, stock=%d, precio=%s}",
                             id, pesoKg, stock, precio);
    }
}

7.2 Utilidad de parseo y casteo

public class ConversorDatos {

    public static void main(String[] args) {
        // Parseo desde consola
        String entrada = "1234";
        int numero = Integer.parseInt(entrada);

        // Casteo entre primitivos
        short corto = (short) numero;

        // Autoboxing / unboxing
        Integer wrapper = numero;   // boxing
        int deNuevo   = wrapper;    // unboxing

        // Conversión a cadena
        String texto = Integer.toString(deNuevo);

        // Wrapper utilities
        System.out.println("Bits usados: " + Integer.SIZE);
        System.out.println("Hex: " + Integer.toHexString(numero));
    }
}

7.3 Ejemplo completo con GUI (consola)

import java.util.Scanner;

public class ConsolaApp {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print("Nombre: ");
        String nombre = sc.nextLine();

        System.out.print("Edad: ");
        int edad = Integer.parseInt(sc.nextLine());

        System.out.print("¿Está activo? (true/false): ");
        boolean activo = Boolean.parseBoolean(sc.nextLine());

        Persona p = new Persona(nombre, edad, activo);
        System.out.println("Registrado -> " + p);
    }
}

class Persona {
    private final String nombre;
    private final int edad;
    private final boolean activo;

    Persona(String nombre, int edad, boolean activo) {
        this.nombre = nombre;
        this.edad   = edad;
        this.activo = activo;
    }

    @Override
    public String toString() {
        return nombre + " (" + edad + " años) - activo=" + activo;
    }
}