Apex Academy
Módulo 1·09·22 min

Casting y conversión de tipos

Cuando el dato que tienes no es del tipo que necesitas. Unas conversiones las hace Apex solo; otras las pides tú, y alguna puede fallar en ejecución.

En Admin esCambiar un campo de Texto a Número en Setup

✓ En esta sub-lección

  1. 01Distinguir la conversión que Apex hace sola de la que tienes que pedir.
  2. 02Pasar de texto a número y de número a texto sin perder datos por el camino.
  3. 03Usar el operador de casting con sObjects y saber por qué puede fallar.

La nutria: ¿Te acuerdas? · Repaso de la lección 8

Quieres las regiones distintas de una lista de cuentas, sin repetidos. ¿Qué colección usas?

Cambiar un campo de Texto a Número en Setup lanza una advertencia: «los datos que no se puedan convertir se perderán». Esa advertencia es, palabra por palabra, de lo que trata esta sub-lección.

String raw = '19.99';
  1. '19.99'String

Paso 1 de 7

El dato llega de un formulario o de una integración, así que llega como texto. Parece un número, pero entre comillas es un String: no sabe multiplicarse.

Hacia arriba nunca se pierde nada, así que Apex no pregunta. Hacia abajo sí, así que tienes que pedirlo.

Lo que Apex hace por su cuenta

Si el valor cabe sin perder nada en el tipo de destino, la conversión es automática. Un Integer cabe en un Decimal, así que puedes asignarlo directamente y nadie protesta. Es la misma lógica que permite ampliar un campo de Texto(40) a Texto(255) sin advertencias.

Apex
Integer units = 5;

Decimal price = units;       // automático: 5 cabe en un Decimal
Long bigNumber = units;      // automático

Decimal total = units * 19.99;   // el Integer se amplía para operar

Lo que tienes que pedir

En sentido contrario hay pérdida: un Decimal en un Integer deja los decimales fuera. Por eso Apex no lo hace solo y hay que llamar a un método que diga qué quieres exactamente: cortar, redondear o ajustar decimales.

MétodoQué hace con 19.99Devuelve
intValue()19: corta, no redondea.Integer
round()20: redondea al entero más cercano.Long
setScale(1)20.0: ajusta los decimales.Decimal
longValue()19: como intValue pero con más rango.Long

Texto y número nunca se convierten solos

Un texto que parece un número sigue siendo un texto: '42' no es 42, igual que en una fórmula necesitabas VALUE() y TEXT(). La conversión se pide con valueOf(), que se le escribe al tipo de destino.

Apex
String raw = '42';

Integer units = Integer.valueOf(raw);       // texto → número entero
Decimal price = Decimal.valueOf('19.99');   // texto → decimal
String label = String.valueOf(42);          // número → texto

// Y funciona con cualquier cosa, no solo números:
String dateText = String.valueOf(Date.today());

La nutria: Convertir y redondear en una línea: TEXT(ROUND(…)) en Apex

La última línea de arriba ya anidaba: Date.today() se resuelve primero y su resultado entra en String.valueOf(). Lo que yo más usaba en la vida real era convertir un importe a texto ya redondeado, lo que en una fórmula sería TEXT(ROUND(Amount, 2)). En Apex: String.valueOf(total.setScale(2)). Se lee de dentro hacia fuera: primero total.setScale(2) da un Decimal con dos decimales, y ese Decimal es el que String.valueOf() convierte a texto. (Simplificación: ROUND() de fórmulas y setScale() no redondean igual en el caso exacto del medio, como 0.125; para importes normales dan lo mismo).
Apex
Decimal total = Decimal.valueOf('1234.5678');

// Desarmado: dos pasos con nombre
Decimal rounded = total.setScale(2);          // 1234.57
String label1 = String.valueOf(rounded);      // '1234.57'

// Anidado: los mismos dos pasos en una línea
String label2 = String.valueOf(total.setScale(2)); // '1234.57'

// Y de texto a número a texto, con un cálculo en medio
String doubled = String.valueOf(Integer.valueOf('21') * 2); // '42'
Lo necesitarás en el checkpoint para mostrar un importe con dos decimales.

El operador de casting: los paréntesis

Hay un tercer caso, y es el que de verdad se llama casting en Apex: cuando tienes un valor guardado en un tipo genérico y quieres tratarlo como el tipo concreto que sabes que es. Se escribe el tipo destino entre paréntesis delante del valor.

Apex
sObject record = new Account(Name = 'Northwind');

// Como sObject, solo se ven los métodos genéricos
Account account = (Account) record;     // casting: ahora es una Account
String name = account.Name;
El casting no transforma el dato: solo cambia cómo lo mira Apex. Debajo siempre fue una Account.

La nutria: Como abrir un registro sin saber de qué objeto es

A mí me ayudó imaginarlo así: un sObject es «un registro de algo»; sabes que es una fila, pero no de qué objeto. El casting es el momento en que dices «esto es una Account» y, a partir de ahí, puedes pedirle Name, Industry o AnnualRevenue. Si te equivocas de objeto, el error no llega al compilar sino al ejecutar, con un TypeException.
Apex
sObject record = new Account(Name = 'Northwind');
Contact wrong = (Contact) record;   // 💥 TypeException en ejecución